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 int size
= supportedPcdType
.size();
141 for (int index
= 0; index
< 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
)) {
171 The pcd type is DynamicEx?
173 @retval true Is DynamicEx type
174 @retval false not DynamicEx type
176 public boolean isDynamicEx() {
177 int size
= supportedPcdType
.size();
178 for (int i
= 0; i
< size
; i
++) {
179 if (supportedPcdType
.get(i
) == PCD_TYPE
.DYNAMIC_EX
) {
188 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
190 @param cName Token name.
191 @param tokenSpaceName The token space guid string defined in MSA or SPD
193 @retval primary key for this token in token database.
195 public static String
getPrimaryKeyString(String cName
, String tokenSpaceName
) {
196 if (tokenSpaceName
== null) {
197 return cName
+ "_nullTokenSpaceGuid";
199 return cName
+ "_" + tokenSpaceName
.toString().replace('-', '_');
204 If skudata list contains more than one data, then Sku mechanism is enable.
206 @retval boolean if the number of sku data exceed to 1
208 public boolean isSkuEnable() {
209 if (this.skuData
.size() > 1) {
216 If Hii type for value of token
220 public boolean isHiiEnable() {
221 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.HII_TYPE
) {
228 If Vpd type for value of token
232 public boolean isVpdEnable() {
233 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.VPD_TYPE
) {
240 Get the token primary key in token database.
244 public String
getPrimaryKeyString () {
245 return Token
.getPrimaryKeyString(cName
, tokenSpaceName
);
249 Judge datumType is valid
251 @param type The datumType want to be judged.
253 @retval TRUE - The type is valid.
254 @retval FALSE - The type is invalid.
256 public static boolean isValiddatumType(DATUM_TYPE type
) {
257 if ((type
.ordinal() < DATUM_TYPE
.UINT8
.ordinal() ) ||
258 (type
.ordinal() > DATUM_TYPE
.POINTER
.ordinal())) {
265 Judge pcdType is valid
267 @param type The PCdType want to be judged.
269 @retval TRUE - The type is valid.
270 @retval FALSE - The type is invalid.
272 public static boolean isValidpcdType(PCD_TYPE type
) {
273 if ((type
.ordinal() < PCD_TYPE
.FEATURE_FLAG
.ordinal() ) ||
274 (type
.ordinal() > PCD_TYPE
.DYNAMIC_EX
.ordinal())) {
281 Add an usage instance for token
283 @param usageInstance The usage instance
285 @retval TRUE - Success to add usage instance.
286 @retval FALSE - Fail to add usage instance
288 public boolean addUsageInstance(UsageInstance usageInstance
) throws EntityException
{
291 if (isUsageInstanceExist(usageInstance
.usageId
)) {
292 exceptionStr
= String
.format("[PCD Collection Tool Exception] PCD %s for module %s has already exist in database, Please check all PCD build entries "+
293 "in modules %s in <ModuleSA> to make sure no duplicated definitions in FPD file!",
294 usageInstance
.parentToken
.cName
,
295 usageInstance
.usageId
.moduleName
,
296 usageInstance
.usageId
.moduleName
);
297 throw new EntityException(exceptionStr
);
301 // Put usage instance into usage instance database of this PCD token.
303 consumers
.put(usageInstance
.getPrimaryKey(), usageInstance
);
309 Judge whether exist an usage instance for this token
311 @param usageId The UsageInstance identification for usage instance
313 @return boolean whether exist an usage instance for this token.
315 public boolean isUsageInstanceExist(UsageIdentification usageId
) {
316 String keyStr
= UsageInstance
.getPrimaryKey(usageId
);
318 return (consumers
.get(keyStr
) != null);
322 Get the PCD_TYPE according to the string of PCD_TYPE
324 @param pcdTypeStr The string of PCD_TYPE
328 public static PCD_TYPE
getPcdTypeFromString(String pcdTypeStr
) {
329 if (pcdTypeStr
== null) {
330 return PCD_TYPE
.UNKNOWN
;
333 if (pcdTypeStr
.equalsIgnoreCase("FEATURE_FLAG")) {
334 return PCD_TYPE
.FEATURE_FLAG
;
335 } else if (pcdTypeStr
.equalsIgnoreCase("FIXED_AT_BUILD")) {
336 return PCD_TYPE
.FIXED_AT_BUILD
;
337 } else if (pcdTypeStr
.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
338 return PCD_TYPE
.PATCHABLE_IN_MODULE
;
339 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC")) {
340 return PCD_TYPE
.DYNAMIC
;
341 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC_EX")) {
342 return PCD_TYPE
.DYNAMIC_EX
;
344 return PCD_TYPE
.UNKNOWN
;
349 Get the string of given datumType. This string will be used for generating autogen files
351 @param datumType Given datumType
353 @return The string of datum type.
355 public static String
getStringOfdatumType(DATUM_TYPE datumType
) {
356 return datumType
.toString();
360 Get the datumType according to a string.
362 @param datumTypeStr The string of datumType
366 public static DATUM_TYPE
getdatumTypeFromString(String datumTypeStr
) {
367 if (datumTypeStr
.equalsIgnoreCase("UINT8")) {
368 return DATUM_TYPE
.UINT8
;
369 } else if (datumTypeStr
.equalsIgnoreCase("UINT16")) {
370 return DATUM_TYPE
.UINT16
;
371 } else if (datumTypeStr
.equalsIgnoreCase("UINT32")) {
372 return DATUM_TYPE
.UINT32
;
373 } else if (datumTypeStr
.equalsIgnoreCase("UINT64")) {
374 return DATUM_TYPE
.UINT64
;
375 } else if (datumTypeStr
.equalsIgnoreCase("VOID*")) {
376 return DATUM_TYPE
.POINTER
;
377 } else if (datumTypeStr
.equalsIgnoreCase("BOOLEAN")) {
378 return DATUM_TYPE
.BOOLEAN
;
380 return DATUM_TYPE
.UNKNOWN
;
384 Get string of given pcdType
386 @param pcdType The given PcdType
388 @return The string of PCD_TYPE.
390 public static String
getStringOfpcdType(PCD_TYPE pcdType
) {
391 return pcdType
.toString();
395 Get the PCD_USAGE according to a string
397 @param usageStr The string of PCD_USAGE
399 @return The PCD_USAGE
401 public static PCD_USAGE
getUsageFromString(String usageStr
) {
402 if (usageStr
== null) {
403 return PCD_USAGE
.UNKNOWN
;
406 if (usageStr
.equalsIgnoreCase("ALWAYS_PRODUCED")) {
407 return PCD_USAGE
.ALWAYS_PRODUCED
;
408 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
409 return PCD_USAGE
.SOMETIMES_PRODUCED
;
410 } else if (usageStr
.equalsIgnoreCase("ALWAYS_CONSUMED")) {
411 return PCD_USAGE
.ALWAYS_CONSUMED
;
412 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
413 return PCD_USAGE
.SOMETIMES_CONSUMED
;
416 return PCD_USAGE
.UNKNOWN
;
420 Get the string of given PCD_USAGE
422 @param usage The given PCD_USAGE
424 @return The string of PDC_USAGE.
426 public static String
getStringOfUsage(PCD_USAGE usage
) {
427 return usage
.toString();
431 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
433 @param datumType The given datumType
435 @return string of datum type for autogen.
437 public static String
GetAutogenDefinedatumTypeString(DATUM_TYPE datumType
) {
458 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
460 @param datumType The given datumType
462 @return string of datum type.
465 public static String
getAutogendatumTypeString(DATUM_TYPE datumType
) {
484 Get the datumType string for generating some MACROs in autogen file of Library
486 @param datumType The given datumType
488 @return String of datum for genrating bit charater.
490 public static String
getAutogenLibrarydatumTypeString(DATUM_TYPE datumType
) {
510 Get the sku data who id is 0.
512 @retval DynamicTokenValue the value of this dyanmic token.
514 public DynamicTokenValue
getDefaultSku() {
516 int size
= skuData
.size();
517 for (index
= 0; index
< size
; index
++) {
518 if (skuData
.get(index
).id
== 0) {
519 return skuData
.get(index
).value
;
527 Get the number of Sku data for this token
529 @retval int the number of sku data
531 public int getSkuIdCount () {
532 return this.skuData
.size();
536 Get the size of PCD value, this PCD is POINTER type.
538 @param str the string of the value
539 @param al the array list for outer parameter.
541 private void getCurrentSizeFromDefaultValue (String str
, ArrayList
<Integer
> al
) {
542 if (isValidNullValue(str
)) {
543 al
.add(new Integer(0));
546 // isValidNullValue has already make sure that str here
547 // always contain a valid default value of the following 3
549 // 1) "Hello world" //Assci string
550 // 2) L"Hello" //Unicode string
551 // 3) {0x01, 0x02, 0x03} //Byte stream
553 if (str
.startsWith("\"")) {
554 al
.add(new Integer(str
.length() - 2));
555 } else if (str
.startsWith("L\"")){
557 // Unicode is 2 bytes each.
559 al
.add(new Integer((str
.length() - 3) * 2));
560 } else if (str
.startsWith("{")) {
562 // We count the number of "," in the string.
563 // The number of byte is one plus the number of
570 pos
= str2
.indexOf(",", 0);
574 pos
= str2
.indexOf(",", pos
);
577 al
.add(new Integer(cnt
));
583 This method can be used to get the MAX and current size
584 for pointer type dynamic(ex) PCD entry
586 public ArrayList
<Integer
> getPointerTypeSize () {
587 ArrayList
<Integer
> al
= new ArrayList
<Integer
>();
590 // For VPD_enabled and HII_enabled, we can only return the MAX size.
591 // For the default DATA type dynamic PCD entry, we will return
592 // the MAX size and current size for each SKU_ID.
594 al
.add(new Integer(this.datumSize
));
596 if (!this.isVpdEnable()) {
598 if (this.isHiiEnable()){
599 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
600 String str
= this.skuData
.get(idx
).value
.hiiDefaultValue
;
601 getCurrentSizeFromDefaultValue(str
, al
);
604 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
605 String str
= this.skuData
.get(idx
).value
.value
;
606 getCurrentSizeFromDefaultValue(str
, al
);
615 Get default value for a token, For HII type, HiiDefaultValue of default
616 SKU 0 will be returned; For Default type, the defaultvalue of default SKU
619 @return String get the default value for a DYNAMIC type PCD.
621 public String
getDynamicDefaultValue() {
622 DynamicTokenValue dynamicData
= getDefaultSku();
623 if (hasDefaultValue()) {
624 switch (dynamicData
.type
) {
626 return dynamicData
.value
;
634 Judge whether a DYNAMIC PCD has default value.
636 @return whether a DYNAMIC PCD has default value.
638 public boolean hasDefaultValue () {
639 DynamicTokenValue dynamicValue
= null;
645 if (this.isDynamicPCD
) {
646 dynamicValue
= getDefaultSku();
647 switch (dynamicValue
.type
) {
653 return !isValidNullValue(dynamicValue
.value
);
661 Judge the value is NULL value. NULL value means the value is uninitialized value
663 @param judgedValue the want want to be judged
665 @return boolean whether the value of PCD is NULL.
667 public boolean isValidNullValue(String judgedValue
) {
669 BigInteger bigIntValue
;
675 if (judgedValue
.length() > 2) {
676 if ((judgedValue
.charAt(0) == '0') &&
677 ((judgedValue
.charAt(1) == 'x') || (judgedValue
.charAt(1) == 'X'))){
678 subStr
= judgedValue
.substring(2, judgedValue
.length());
679 bigIntValue
= new BigInteger(subStr
, 16);
681 bigIntValue
= new BigInteger(judgedValue
);
684 bigIntValue
= new BigInteger(judgedValue
);
686 if (bigIntValue
.bitCount() == 0) {
691 if (judgedValue
.length() > 2){
692 if ((judgedValue
.charAt(0) == '0') &&
693 ((judgedValue
.charAt(1) == 'x') ||
694 (judgedValue
.charAt(1) == 'X'))) {
695 bigIntValue
= new BigInteger(judgedValue
.substring(2, judgedValue
.length()), 16);
696 if (bigIntValue
.bitCount() == 0) {
700 bigIntValue
= new BigInteger(judgedValue
);
701 if (bigIntValue
.bitCount() == 0) {
706 bigIntValue
= new BigInteger(judgedValue
);
707 if (bigIntValue
.bitCount() == 0) {
713 if (judgedValue
.equalsIgnoreCase("false")) {
718 if (judgedValue
.equalsIgnoreCase("\"\"") ||
719 judgedValue
.equalsIgnoreCase("L\"\"") ||
720 (judgedValue
.length() == 0)) {
722 } else if (judgedValue
.trim().charAt(0) == '{') {
723 int start
= judgedValue
.indexOf('{');
724 int end
= judgedValue
.lastIndexOf('}');
725 String
[] strValueArray
= judgedValue
.substring(start
+ 1, end
).split(",");
726 if (strValueArray
.length
> 1) {
729 if (strValueArray
[0].matches("(0x)?(0X)?0*")) {
739 Is the string value in Unicode
741 @return boolean the string value is UNICODE type string.
743 public boolean isHiiDefaultValueUnicodeStringType() {
744 DynamicTokenValue dynamicData
= getDefaultSku();
746 if (dynamicData
== null)
749 return dynamicData
.hiiDefaultValue
.startsWith("L\"")
750 && dynamicData
.hiiDefaultValue
.endsWith("\"");
754 Is the string value in ANSCI
756 @return boolean whether the dfault value for HII case is string type.
758 public boolean isHiiDefaultValueASCIIStringType() {
759 DynamicTokenValue dynamicData
= getDefaultSku();
761 if (dynamicData
== null)
764 return dynamicData
.hiiDefaultValue
.startsWith("\"")
765 && dynamicData
.hiiDefaultValue
.endsWith("\"");
769 Judege whether current value is UNICODE string type.
771 @return boolean whether the value is UNICODE string.
773 public boolean isUnicodeStringType () {
774 String str
= getDynamicDefaultValue();
780 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
781 str
.startsWith("L\"") &&
782 str
.endsWith("\"")) {
790 Judge whether the string type is ANSIC string.
792 @return boolean whether the string type is ANSIC string
794 public boolean isASCIIStringType () {
795 String str
= getDynamicDefaultValue();
801 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
802 str
.startsWith("\"") &&
803 str
.endsWith("\"")) {
811 Judge whether the string value is byte array.
813 @return boolean whether the string value is byte array.
816 public boolean isByteStreamType () {
817 String str
= getDynamicDefaultValue();
823 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
824 str
.startsWith("{") &&
834 Get string value for ANSIC string type
836 @return String the string value
838 public String
getStringTypeString () {
839 return getDefaultSku().value
.substring(2, getDefaultSku().value
.length() - 1);