]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
bce2ec9ad21ecea6119a3d6e1a5de986b5b67b5e
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / entity / Token.java
1 /** @file
2 Token class.
3
4 This module contains all classes releted to PCD token.
5
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
11
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.
14
15 **/
16 package org.tianocore.build.pcd.entity;
17
18 import java.math.BigInteger;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.UUID;
24
25 import org.tianocore.build.pcd.action.ActionMessage;
26 import org.tianocore.build.pcd.exception.EntityException;
27
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.
30 **/
31 public class Token {
32 ///
33 /// Enumeration macro defintion for PCD type.
34 /// BUGBUG: Not use upcase charater is to facility for reading. It may be changed
35 /// in coding review.
36 public enum PCD_TYPE {FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODULE, DYNAMIC,
37 DYNAMIC_EX, UNKNOWN}
38
39 ///
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
42 /// prompt dialog.
43 ///
44 public enum DATUM_TYPE {UINT8, UINT16, UINT32, UINT64, BOOLEAN, POINTER, UNKNOWN}
45
46 ///
47 /// Enumeration macor defintion for usage of PCD
48 ///
49 public enum PCD_USAGE {ALWAYS_PRODUCED, ALWAYS_CONSUMED, SOMETIMES_PRODUCED,
50 SOMETIMES_CONSUMED, UNKNOWN}
51
52 ///
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.
55 ///
56 public String cName;
57
58 ///
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.
63 ///
64 public UUID tokenSpaceName;
65
66 ///
67 /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in
68 /// platform token space.
69 /// tokenNumber is defined in SPD, FPD.
70 ///
71 public int tokenNumber;
72
73 ///
74 /// All supported PCD type, this value can be retrieved from SPD
75 /// Currently, only record all PCD type for this token in FPD file.
76 ///
77 public List<PCD_TYPE> supportedPcdType;
78
79 ///
80 /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD
81 /// is true.
82 ///
83 public boolean isDynamicPCD;
84
85 ///
86 /// datumSize is to descript the fix size or max size for this token.
87 /// datumSize is defined in SPD.
88 ///
89 public int datumSize;
90
91 ///
92 /// datum type is to descript what type can be expressed by a PCD token.
93 /// For same PCD used in different module, the datum type should be unique.
94 /// So it belong memeber to Token class.
95 ///
96 public DATUM_TYPE datumType;
97
98 ///
99 /// skuData contains all value for SkuNumber of token.
100 /// This field is for Dynamic or DynamicEx type PCD,
101 ///
102 public List<SkuInstance> skuData;
103
104 ///
105 /// consumers array record all module private information who consume this PCD token.
106 ///
107 public Map<String, UsageInstance> consumers;
108
109 public Token(String cName, UUID tokenSpaceName) {
110 UUID nullUUID = new UUID(0, 0);
111
112 this.cName = cName;
113 this.tokenSpaceName = (tokenSpaceName == null) ? nullUUID : tokenSpaceName;
114 this.tokenNumber = 0;
115 this.datumType = DATUM_TYPE.UNKNOWN;
116 this.datumSize = -1;
117 this.skuData = new ArrayList<SkuInstance>();
118
119 this.consumers = new HashMap<String, UsageInstance>();
120 this.supportedPcdType = new ArrayList<PCD_TYPE>();
121 }
122
123 /**
124 updateSupportPcdType
125
126 SupportPcdType should be gotten from SPD file actually, but now it just
127 record all PCD type for this token in FPD file.
128
129 @param pcdType new PCD type found in FPD file for this token.
130 **/
131 public void updateSupportPcdType(PCD_TYPE pcdType) {
132 int index = 0;
133 boolean found = false;
134 for (index = 0; index < this.supportedPcdType.size(); index ++) {
135 if (this.supportedPcdType.get(index) == pcdType) {
136 found = true;
137 break;
138 }
139 }
140 if (!found) {
141 this.supportedPcdType.add(pcdType);
142 }
143 }
144
145 /**
146 Judge whether pcdType is belong to dynamic type. Dynamic type includes
147 DYNAMIC and DYNAMIC_EX.
148
149 @param pcdType
150
151 @return boolean
152 */
153 public static boolean isDynamic(PCD_TYPE pcdType) {
154 if ((pcdType == PCD_TYPE.DYNAMIC ) ||
155 (pcdType == PCD_TYPE.DYNAMIC_EX)) {
156 return true;
157 }
158
159 return false;
160 }
161
162 /**
163 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
164
165 @param cName Token name.
166 @param tokenSpaceName The token space guid defined in MSA or SPD
167 @param platformtokenSpaceName The token space guid for current platform token space,
168
169 @return primary key for this token in token database.
170 **/
171 public static String getPrimaryKeyString(String cName, UUID tokenSpaceName) {
172 UUID nullUUID = new UUID(0, 0);
173
174 if (tokenSpaceName == null) {
175 return cName + "_" + nullUUID.toString().replace('-', '_');
176 } else {
177 return cName + "_" + tokenSpaceName.toString().replace('-', '_');
178 }
179 }
180
181 /**
182 If skudata list contains more than one data, then Sku mechanism is enable.
183
184 @return boolean
185 */
186 public boolean isSkuEnable() {
187 if (this.skuData.size() > 1) {
188 return true;
189 }
190 return false;
191 }
192
193 /**
194 Get the token primary key in token database.
195
196 @return String
197 */
198 public String getPrimaryKeyString () {
199 return Token.getPrimaryKeyString(cName, tokenSpaceName);
200 }
201
202 /**
203 Judge datumType is valid
204
205 @param type The datumType want to be judged.
206
207 @retval TRUE - The type is valid.
208 @retval FALSE - The type is invalid.
209 **/
210 public static boolean isValiddatumType(DATUM_TYPE type) {
211 if ((type.ordinal() < DATUM_TYPE.UINT8.ordinal() ) ||
212 (type.ordinal() > DATUM_TYPE.POINTER.ordinal())) {
213 return false;
214 }
215 return true;
216 }
217
218 /**
219 Judge pcdType is valid
220
221 @param type The PCdType want to be judged.
222
223 @retval TRUE - The type is valid.
224 @retval FALSE - The type is invalid.
225 **/
226 public static boolean isValidpcdType(PCD_TYPE type) {
227 if ((type.ordinal() < PCD_TYPE.FEATURE_FLAG.ordinal() ) ||
228 (type.ordinal() > PCD_TYPE.DYNAMIC_EX.ordinal())) {
229 return false;
230 }
231 return true;
232 }
233
234 /**
235 Add an usage instance for token
236
237 @param usageInstance The usage instance
238
239 @retval TRUE - Success to add usage instance.
240 @retval FALSE - Fail to add usage instance
241 **/
242 public boolean addUsageInstance(UsageInstance usageInstance)
243 throws EntityException {
244 String exceptionStr;
245
246 if (isUsageInstanceExist(usageInstance.moduleName,
247 usageInstance.moduleGUID,
248 usageInstance.packageName,
249 usageInstance.packageGUID,
250 usageInstance.arch,
251 usageInstance.version)) {
252 exceptionStr = String.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+
253 "in modules PcdPeim in <ModuleSA> to make sure no duplicated definitions!",
254 usageInstance.parentToken.cName,
255 usageInstance.moduleName);
256 throw new EntityException(exceptionStr);
257 }
258
259 consumers.put(usageInstance.getPrimaryKey(), usageInstance);
260 return true;
261 }
262
263 /**
264 Judge whether exist an usage instance for this token
265
266 @param moduleName the name of module
267 @param moduleGuid the GUID name of modules
268 @param packageName the name of package contains this module
269 @param packageGuid the GUID name of package contains this module
270 @param arch the architecture string
271 @param version the version string
272
273 @return boolean whether exist an usage instance for this token.
274 */
275 public boolean isUsageInstanceExist(String moduleName,
276 UUID moduleGuid,
277 String packageName,
278 UUID packageGuid,
279 String arch,
280 String version) {
281 String keyStr = UsageInstance.getPrimaryKey(moduleName,
282 moduleGuid,
283 packageName,
284 packageGuid,
285 arch,
286 version);
287 return (consumers.get(keyStr) != null);
288 }
289
290 /**
291 Get the PCD_TYPE according to the string of PCD_TYPE
292
293 @param pcdTypeStr The string of PCD_TYPE
294
295 @return PCD_TYPE
296 **/
297 public static PCD_TYPE getpcdTypeFromString(String pcdTypeStr) {
298 if (pcdTypeStr == null) {
299 return PCD_TYPE.UNKNOWN;
300 }
301
302 if (pcdTypeStr.equalsIgnoreCase("FEATURE_FLAG")) {
303 return PCD_TYPE.FEATURE_FLAG;
304 } else if (pcdTypeStr.equalsIgnoreCase("FIXED_AT_BUILD")) {
305 return PCD_TYPE.FIXED_AT_BUILD;
306 } else if (pcdTypeStr.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
307 return PCD_TYPE.PATCHABLE_IN_MODULE;
308 } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC")) {
309 return PCD_TYPE.DYNAMIC;
310 } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC_EX")) {
311 return PCD_TYPE.DYNAMIC_EX;
312 } else {
313 return PCD_TYPE.UNKNOWN;
314 }
315 }
316
317 /**
318 Get the string of given datumType. This string will be used for generating autogen files
319
320 @param datumType Given datumType
321
322 @return The string of datum type.
323 **/
324 public static String getStringOfdatumType(DATUM_TYPE datumType) {
325 switch (datumType) {
326 case UINT8:
327 return "UINT8";
328 case UINT16:
329 return "UINT16";
330 case UINT32:
331 return "UINT32";
332 case UINT64:
333 return "UINT64";
334 case POINTER:
335 return "POINTER";
336 case BOOLEAN:
337 return "BOOLEAN";
338 }
339 return "UNKNOWN";
340 }
341
342 /**
343 Get the datumType according to a string.
344
345 @param datumTypeStr The string of datumType
346
347 @return DATUM_TYPE
348 **/
349 public static DATUM_TYPE getdatumTypeFromString(String datumTypeStr) {
350 if (datumTypeStr.equalsIgnoreCase("UINT8")) {
351 return DATUM_TYPE.UINT8;
352 } else if (datumTypeStr.equalsIgnoreCase("UINT16")) {
353 return DATUM_TYPE.UINT16;
354 } else if (datumTypeStr.equalsIgnoreCase("UINT32")) {
355 return DATUM_TYPE.UINT32;
356 } else if (datumTypeStr.equalsIgnoreCase("UINT64")) {
357 return DATUM_TYPE.UINT64;
358 } else if (datumTypeStr.equalsIgnoreCase("VOID*")) {
359 return DATUM_TYPE.POINTER;
360 } else if (datumTypeStr.equalsIgnoreCase("BOOLEAN")) {
361 return DATUM_TYPE.BOOLEAN;
362 }
363 return DATUM_TYPE.UNKNOWN;
364 }
365
366 /**
367 Get string of given pcdType
368
369 @param pcdType The given PcdType
370
371 @return The string of PCD_TYPE.
372 **/
373 public static String getStringOfpcdType(PCD_TYPE pcdType) {
374 switch (pcdType) {
375 case FEATURE_FLAG:
376 return "FEATURE_FLAG";
377 case FIXED_AT_BUILD:
378 return "FIXED_AT_BUILD";
379 case PATCHABLE_IN_MODULE:
380 return "PATCHABLE_IN_MODULE";
381 case DYNAMIC:
382 return "DYNAMIC";
383 case DYNAMIC_EX:
384 return "DYNAMIC_EX";
385 }
386 return "UNKNOWN";
387 }
388
389 /**
390 Get the PCD_USAGE according to a string
391
392 @param usageStr The string of PCD_USAGE
393
394 @return The PCD_USAGE
395 **/
396 public static PCD_USAGE getUsageFromString(String usageStr) {
397 if (usageStr == null) {
398 return PCD_USAGE.UNKNOWN;
399 }
400
401 if (usageStr.equalsIgnoreCase("ALWAYS_PRODUCED")) {
402 return PCD_USAGE.ALWAYS_PRODUCED;
403 } else if (usageStr.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
404 return PCD_USAGE.SOMETIMES_PRODUCED;
405 } else if (usageStr.equalsIgnoreCase("ALWAYS_CONSUMED")) {
406 return PCD_USAGE.ALWAYS_CONSUMED;
407 } else if (usageStr.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
408 return PCD_USAGE.SOMETIMES_CONSUMED;
409 }
410
411 return PCD_USAGE.UNKNOWN;
412 }
413
414 /**
415 Get the string of given PCD_USAGE
416
417 @param usage The given PCD_USAGE
418
419 @return The string of PDC_USAGE.
420 **/
421 public static String getStringOfUsage(PCD_USAGE usage) {
422 switch (usage) {
423 case ALWAYS_PRODUCED:
424 return "ALWAYS_PRODUCED";
425 case ALWAYS_CONSUMED:
426 return "ALWAYS_CONSUMED";
427 case SOMETIMES_PRODUCED:
428 return "SOMETIMES_PRODUCED";
429 case SOMETIMES_CONSUMED:
430 return "SOMETIMES_CONSUMED";
431 }
432 return "UNKNOWN";
433 }
434
435 /**
436 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
437
438 @param datumType The given datumType
439
440 @return string of datum type for autogen.
441 **/
442 public static String GetAutogenDefinedatumTypeString(DATUM_TYPE datumType) {
443 switch (datumType) {
444
445 case UINT8:
446 return "8";
447 case UINT16:
448 return "16";
449 case BOOLEAN:
450 return "BOOL";
451 case POINTER:
452 return "PTR";
453 case UINT32:
454 return "32";
455 case UINT64:
456 return "64";
457 default:
458 return null;
459 }
460 }
461
462 /**
463 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
464
465 @param datumType The given datumType
466
467 @return string of datum type.
468 **/
469 public static String getAutogendatumTypeString(DATUM_TYPE datumType) {
470 switch (datumType) {
471 case UINT8:
472 return "UINT8";
473 case UINT16:
474 return "UINT16";
475 case UINT32:
476 return "UINT32";
477 case UINT64:
478 return "UINT64";
479 case POINTER:
480 return "VOID*";
481 case BOOLEAN:
482 return "BOOLEAN";
483 }
484 return null;
485 }
486
487 /**
488 Get the datumType string for generating some MACROs in autogen file of Library
489
490 @param datumType The given datumType
491
492 @return String of datum for genrating bit charater.
493 **/
494 public static String getAutogenLibrarydatumTypeString(DATUM_TYPE datumType) {
495 switch (datumType) {
496 case UINT8:
497 return "8";
498 case UINT16:
499 return "16";
500 case BOOLEAN:
501 return "Bool";
502 case POINTER:
503 return "Ptr";
504 case UINT32:
505 return "32";
506 case UINT64:
507 return "64";
508 default:
509 return null;
510 }
511 }
512
513 /**
514 UUID defined in Schems is object, this function is to tranlate this object
515 to UUID data.
516
517 @param uuidObj The object comes from schema.
518
519 @return The traslated UUID instance.
520 **/
521 public static UUID getGUIDFromSchemaObject(Object uuidObj) {
522 UUID uuid;
523 if (uuidObj.toString().equalsIgnoreCase("0")) {
524 uuid = new UUID(0,0);
525 } else {
526 uuid = UUID.fromString(uuidObj.toString());
527 }
528
529 return uuid;
530 }
531
532 public DynamicTokenValue getDefaultSku() {
533 DynamicTokenValue dynamicData;
534 int index;
535 for (index = 0; index < this.skuData.size(); index ++) {
536 if (skuData.get(index).id == 0) {
537 return skuData.get(index).value;
538 }
539 }
540
541 return null;
542 }
543
544 /**
545 Get default value for a token, For HII type, HiiDefaultValue of default
546 SKU 0 will be returned; For Default type, the defaultvalue of default SKU
547 0 will be returned.
548
549 @return String
550 */
551 public String getDynamicDefaultValue() {
552 DynamicTokenValue dynamicData = getDefaultSku();
553 if (hasDefaultValue()) {
554 switch (dynamicData.type) {
555 case HII_TYPE:
556 return dynamicData.hiiDefaultValue;
557 case DEFAULT_TYPE:
558 return dynamicData.value;
559 }
560 }
561
562 return null;
563 }
564
565 //
566 // BugBug: We need change this algorithm accordingly when schema is updated
567 // to support no default value.
568 //
569 public boolean hasDefaultValue () {
570 int value = 0;
571 boolean isInteger = true;
572 DynamicTokenValue dynamicValue = null;
573
574 if (this.isDynamicPCD) {
575 dynamicValue = getDefaultSku();
576 switch (dynamicValue.type) {
577 case HII_TYPE:
578 return !isValidNullValue(dynamicValue.hiiDefaultValue);
579 case VPD_TYPE:
580 return false;
581 case DEFAULT_TYPE:
582 return !isValidNullValue(dynamicValue.value);
583 }
584 }
585
586 return false;
587 }
588
589 public boolean isValidNullValue(String judgedValue) {
590 int intValue;
591 BigInteger bigIntValue;
592
593 switch (datumType) {
594 case UINT8:
595 case UINT16:
596 case UINT32:
597 intValue = Integer.decode(judgedValue);
598 if (intValue == 0) {
599 return true;
600 }
601 break;
602 case UINT64:
603 if (judgedValue.length() > 2){
604 if ((judgedValue.charAt(0) == '0') &&
605 ((judgedValue.charAt(1) == 'x') ||
606 (judgedValue.charAt(1) == 'X'))) {
607 bigIntValue = new BigInteger(judgedValue.substring(2, judgedValue.length()), 16);
608 if (bigIntValue.bitCount() == 0) {
609 return true;
610 }
611 } else {
612 bigIntValue = new BigInteger(judgedValue);
613 if (bigIntValue.bitCount() == 0) {
614 return true;
615 }
616 }
617 } else {
618 bigIntValue = new BigInteger(judgedValue);
619 if (bigIntValue.bitCount() == 0) {
620 return true;
621 }
622 }
623 break;
624 case BOOLEAN:
625 if (judgedValue.equalsIgnoreCase("false")) {
626 return true;
627 }
628 break;
629 case POINTER:
630 if (judgedValue.equalsIgnoreCase("") ||
631 judgedValue.equalsIgnoreCase("\"\"") ||
632 judgedValue.equalsIgnoreCase("L\"\"") ||
633 (judgedValue.length() == 0) ||
634 judgedValue.equalsIgnoreCase("{}")) {
635 return true;
636 }
637 }
638 return false;
639 }
640
641 /**
642 Judege whether current value is UNICODE string type.
643 @return boolean
644 */
645 public boolean isUnicodeStringType () {
646 String str = getDynamicDefaultValue();
647
648 if (str == null) {
649 return false;
650 }
651
652 if (datumType == Token.DATUM_TYPE.POINTER &&
653 str.startsWith("L\"") &&
654 str.endsWith("\"")) {
655 return true;
656 }
657
658 return false;
659 }
660
661 public String getStringTypeString () {
662 return getDefaultSku().value.substring(2, getDefaultSku().value.length() - 1);
663 }
664 }
665
666
667
668