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. For Dynamic, dynamicEx type, this number will be re-adjust by
69 /// PCD run-time database autogen tools.
71 public int tokenNumber
;
74 /// This token number is retrieved from FPD file for DynamicEx type.
76 public int 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
;
114 public Token(String cName
, UUID tokenSpaceName
) {
115 UUID nullUUID
= new UUID(0, 0);
118 this.tokenSpaceName
= (tokenSpaceName
== null) ? nullUUID
: 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
) {
138 boolean found
= false;
139 for (index
= 0; index
< this.supportedPcdType
.size(); index
++) {
140 if (this.supportedPcdType
.get(index
) == pcdType
) {
146 this.supportedPcdType
.add(pcdType
);
151 Judge whether pcdType is belong to dynamic type. Dynamic type includes
152 DYNAMIC and DYNAMIC_EX.
158 public static boolean isDynamic(PCD_TYPE pcdType
) {
159 if ((pcdType
== PCD_TYPE
.DYNAMIC
) ||
160 (pcdType
== PCD_TYPE
.DYNAMIC_EX
)) {
168 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
170 @param cName Token name.
171 @param tokenSpaceName The token space guid defined in MSA or SPD
172 @param platformtokenSpaceName The token space guid for current platform token space,
174 @return primary key for this token in token database.
176 public static String
getPrimaryKeyString(String cName
, UUID tokenSpaceName
) {
177 UUID nullUUID
= new UUID(0, 0);
179 if (tokenSpaceName
== null) {
180 return cName
+ "_" + nullUUID
.toString().replace('-', '_');
182 return cName
+ "_" + tokenSpaceName
.toString().replace('-', '_');
187 If skudata list contains more than one data, then Sku mechanism is enable.
191 public boolean isSkuEnable() {
192 if (this.skuData
.size() > 1) {
199 Get the token primary key in token database.
203 public String
getPrimaryKeyString () {
204 return Token
.getPrimaryKeyString(cName
, tokenSpaceName
);
208 Judge datumType is valid
210 @param type The datumType want to be judged.
212 @retval TRUE - The type is valid.
213 @retval FALSE - The type is invalid.
215 public static boolean isValiddatumType(DATUM_TYPE type
) {
216 if ((type
.ordinal() < DATUM_TYPE
.UINT8
.ordinal() ) ||
217 (type
.ordinal() > DATUM_TYPE
.POINTER
.ordinal())) {
224 Judge pcdType is valid
226 @param type The PCdType want to be judged.
228 @retval TRUE - The type is valid.
229 @retval FALSE - The type is invalid.
231 public static boolean isValidpcdType(PCD_TYPE type
) {
232 if ((type
.ordinal() < PCD_TYPE
.FEATURE_FLAG
.ordinal() ) ||
233 (type
.ordinal() > PCD_TYPE
.DYNAMIC_EX
.ordinal())) {
240 Add an usage instance for token
242 @param usageInstance The usage instance
244 @retval TRUE - Success to add usage instance.
245 @retval FALSE - Fail to add usage instance
247 public boolean addUsageInstance(UsageInstance usageInstance
)
248 throws EntityException
{
251 if (isUsageInstanceExist(usageInstance
.moduleName
,
252 usageInstance
.moduleGUID
,
253 usageInstance
.packageName
,
254 usageInstance
.packageGUID
,
256 usageInstance
.version
)) {
257 exceptionStr
= String
.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+
258 "in modules PcdPeim in <ModuleSA> to make sure no duplicated definitions!",
259 usageInstance
.parentToken
.cName
,
260 usageInstance
.moduleName
);
261 throw new EntityException(exceptionStr
);
264 consumers
.put(usageInstance
.getPrimaryKey(), usageInstance
);
269 Judge whether exist an usage instance for this token
271 @param moduleName the name of module
272 @param moduleGuid the GUID name of modules
273 @param packageName the name of package contains this module
274 @param packageGuid the GUID name of package contains this module
275 @param arch the architecture string
276 @param version the version string
278 @return boolean whether exist an usage instance for this token.
280 public boolean isUsageInstanceExist(String moduleName
,
286 String keyStr
= UsageInstance
.getPrimaryKey(moduleName
,
292 return (consumers
.get(keyStr
) != null);
296 Get the PCD_TYPE according to the string of PCD_TYPE
298 @param pcdTypeStr The string of PCD_TYPE
302 public static PCD_TYPE
getpcdTypeFromString(String pcdTypeStr
) {
303 if (pcdTypeStr
== null) {
304 return PCD_TYPE
.UNKNOWN
;
307 if (pcdTypeStr
.equalsIgnoreCase("FEATURE_FLAG")) {
308 return PCD_TYPE
.FEATURE_FLAG
;
309 } else if (pcdTypeStr
.equalsIgnoreCase("FIXED_AT_BUILD")) {
310 return PCD_TYPE
.FIXED_AT_BUILD
;
311 } else if (pcdTypeStr
.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
312 return PCD_TYPE
.PATCHABLE_IN_MODULE
;
313 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC")) {
314 return PCD_TYPE
.DYNAMIC
;
315 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC_EX")) {
316 return PCD_TYPE
.DYNAMIC_EX
;
318 return PCD_TYPE
.UNKNOWN
;
323 Get the string of given datumType. This string will be used for generating autogen files
325 @param datumType Given datumType
327 @return The string of datum type.
329 public static String
getStringOfdatumType(DATUM_TYPE datumType
) {
348 Get the datumType according to a string.
350 @param datumTypeStr The string of datumType
354 public static DATUM_TYPE
getdatumTypeFromString(String datumTypeStr
) {
355 if (datumTypeStr
.equalsIgnoreCase("UINT8")) {
356 return DATUM_TYPE
.UINT8
;
357 } else if (datumTypeStr
.equalsIgnoreCase("UINT16")) {
358 return DATUM_TYPE
.UINT16
;
359 } else if (datumTypeStr
.equalsIgnoreCase("UINT32")) {
360 return DATUM_TYPE
.UINT32
;
361 } else if (datumTypeStr
.equalsIgnoreCase("UINT64")) {
362 return DATUM_TYPE
.UINT64
;
363 } else if (datumTypeStr
.equalsIgnoreCase("VOID*")) {
364 return DATUM_TYPE
.POINTER
;
365 } else if (datumTypeStr
.equalsIgnoreCase("BOOLEAN")) {
366 return DATUM_TYPE
.BOOLEAN
;
368 return DATUM_TYPE
.UNKNOWN
;
372 Get string of given pcdType
374 @param pcdType The given PcdType
376 @return The string of PCD_TYPE.
378 public static String
getStringOfpcdType(PCD_TYPE pcdType
) {
381 return "FEATURE_FLAG";
383 return "FIXED_AT_BUILD";
384 case PATCHABLE_IN_MODULE
:
385 return "PATCHABLE_IN_MODULE";
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
) {
428 case ALWAYS_PRODUCED
:
429 return "ALWAYS_PRODUCED";
430 case ALWAYS_CONSUMED
:
431 return "ALWAYS_CONSUMED";
432 case SOMETIMES_PRODUCED
:
433 return "SOMETIMES_PRODUCED";
434 case SOMETIMES_CONSUMED
:
435 return "SOMETIMES_CONSUMED";
441 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
443 @param datumType The given datumType
445 @return string of datum type for autogen.
447 public static String
GetAutogenDefinedatumTypeString(DATUM_TYPE datumType
) {
468 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
470 @param datumType The given datumType
472 @return string of datum type.
474 public static String
getAutogendatumTypeString(DATUM_TYPE datumType
) {
493 Get the datumType string for generating some MACROs in autogen file of Library
495 @param datumType The given datumType
497 @return String of datum for genrating bit charater.
499 public static String
getAutogenLibrarydatumTypeString(DATUM_TYPE datumType
) {
519 UUID defined in Schems is object, this function is to tranlate this object
522 @param uuidObj The object comes from schema.
524 @return The traslated UUID instance.
526 public static UUID
getGUIDFromSchemaObject(Object uuidObj
) {
528 if (uuidObj
.toString().equalsIgnoreCase("0")) {
529 uuid
= new UUID(0,0);
531 uuid
= UUID
.fromString(uuidObj
.toString());
537 public DynamicTokenValue
getDefaultSku() {
538 DynamicTokenValue dynamicData
;
540 for (index
= 0; index
< this.skuData
.size(); index
++) {
541 if (skuData
.get(index
).id
== 0) {
542 return skuData
.get(index
).value
;
550 Get default value for a token, For HII type, HiiDefaultValue of default
551 SKU 0 will be returned; For Default type, the defaultvalue of default SKU
556 public String
getDynamicDefaultValue() {
557 DynamicTokenValue dynamicData
= getDefaultSku();
558 if (hasDefaultValue()) {
559 switch (dynamicData
.type
) {
561 return dynamicData
.hiiDefaultValue
;
563 return dynamicData
.value
;
571 // BugBug: We need change this algorithm accordingly when schema is updated
572 // to support no default value.
574 public boolean hasDefaultValue () {
576 boolean isInteger
= true;
577 DynamicTokenValue dynamicValue
= null;
579 if (this.isDynamicPCD
) {
580 dynamicValue
= getDefaultSku();
581 switch (dynamicValue
.type
) {
583 return !isValidNullValue(dynamicValue
.hiiDefaultValue
);
587 return !isValidNullValue(dynamicValue
.value
);
594 public boolean isValidNullValue(String judgedValue
) {
596 BigInteger bigIntValue
;
602 intValue
= Integer
.decode(judgedValue
);
608 if (judgedValue
.length() > 2){
609 if ((judgedValue
.charAt(0) == '0') &&
610 ((judgedValue
.charAt(1) == 'x') ||
611 (judgedValue
.charAt(1) == 'X'))) {
612 bigIntValue
= new BigInteger(judgedValue
.substring(2, judgedValue
.length()), 16);
613 if (bigIntValue
.bitCount() == 0) {
617 bigIntValue
= new BigInteger(judgedValue
);
618 if (bigIntValue
.bitCount() == 0) {
623 bigIntValue
= new BigInteger(judgedValue
);
624 if (bigIntValue
.bitCount() == 0) {
630 if (judgedValue
.equalsIgnoreCase("false")) {
635 if (judgedValue
.equalsIgnoreCase("") ||
636 judgedValue
.equalsIgnoreCase("\"\"") ||
637 judgedValue
.equalsIgnoreCase("L\"\"") ||
638 (judgedValue
.length() == 0) ||
639 judgedValue
.equalsIgnoreCase("{}")) {
647 Judege whether current value is UNICODE string type.
650 public boolean isUnicodeStringType () {
651 String str
= getDynamicDefaultValue();
657 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
658 str
.startsWith("L\"") &&
659 str
.endsWith("\"")) {
666 public String
getStringTypeString () {
667 return getDefaultSku().value
.substring(2, getDefaultSku().value
.length() - 1);