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