]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java
9a8699cfe4b9cf01c5f8f42f39172df85727e1e9
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PcdDatabase.java
1 /** @file
2 PcdDatabase class.
3
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14 package org.tianocore.build.pcd.action;
15
16 import java.io.BufferedReader;
17 import java.io.File;
18 import java.io.FileReader;
19 import java.io.IOException;
20 import java.math.BigInteger;
21 import java.util.ArrayList;
22 import java.util.Comparator;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.UUID;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31
32 import org.apache.xmlbeans.XmlException;
33 import org.apache.xmlbeans.XmlObject;
34 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;
35 import org.tianocore.FrameworkModulesDocument;
36 import org.tianocore.ModuleSADocument;
37 import org.tianocore.PcdBuildDefinitionDocument;
38 import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;
39 import org.tianocore.PlatformSurfaceAreaDocument;
40 import org.tianocore.build.fpd.FpdParserTask;
41 import org.tianocore.build.global.GlobalData;
42 import org.tianocore.build.id.FpdModuleIdentification;
43 import org.tianocore.build.id.ModuleIdentification;
44 import org.tianocore.pcd.action.ActionMessage;
45 import org.tianocore.pcd.entity.CommonDefinition;
46 import org.tianocore.pcd.entity.DynamicTokenValue;
47 import org.tianocore.pcd.entity.MemoryDatabaseManager;
48 import org.tianocore.pcd.entity.SkuInstance;
49 import org.tianocore.pcd.entity.Token;
50 import org.tianocore.pcd.entity.UsageIdentification;
51 import org.tianocore.pcd.entity.UsageInstance;
52 import org.tianocore.pcd.exception.EntityException;
53
54 /**
55 CStructTypeDeclaration
56
57 This class is used to store the declaration string, such as
58 "UINT32 PcdPlatformFlashBaseAddress", of
59 each memember in the C structure, which is a standard C language
60 feature used to implement a simple and efficient database for
61 dynamic(ex) type PCD entry.
62 **/
63 class CStructTypeDeclaration {
64 String key;
65 int alignmentSize;
66 String cCode;
67 boolean initTable;
68
69 public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {
70 this.key = key;
71 this.alignmentSize = alignmentSize;
72 this.cCode = cCode;
73 this.initTable = initTable;
74 }
75 }
76
77 /**
78 StringTable
79
80 This class is used to store the String in a PCD database.
81
82 **/
83 class StringTable {
84 private ArrayList<String> al;
85 private ArrayList<String> alComments;
86 private String phase;
87 int len;
88
89 public StringTable (String phase) {
90 this.phase = phase;
91 al = new ArrayList<String>();
92 alComments = new ArrayList<String>();
93 len = 0;
94 }
95
96 public String getSizeMacro () {
97 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());
98 }
99
100 private int getSize () {
101 //
102 // We have at least one Unicode Character in the table.
103 //
104 return len == 0 ? 1 : len;
105 }
106
107 public String getExistanceMacro () {
108 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
109 }
110
111 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {
112 final String stringTable = "StringTable";
113 final String tab = "\t";
114 final String newLine = "\r\n";
115 final String commaNewLine = ",\r\n";
116
117 CStructTypeDeclaration decl;
118
119 String cDeclCode = "";
120 String cInstCode = "";
121
122 //
123 // If we have a empty StringTable
124 //
125 if (al.size() == 0) {
126 cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine;
127 decl = new CStructTypeDeclaration (
128 stringTable,
129 2,
130 cDeclCode,
131 true
132 );
133 declaList.add(decl);
134
135 cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";
136 instTable.put(stringTable, cInstCode);
137 } else {
138
139 //
140 // If there is any String in the StringTable
141 //
142 for (int i = 0; i < al.size(); i++) {
143 String str = al.get(i);
144 String stringTableName;
145
146 if (i == 0) {
147 //
148 // StringTable is a well-known name in the PCD DXE driver
149 //
150 stringTableName = stringTable;
151
152 } else {
153 stringTableName = String.format("%s_%d", stringTable, i);
154 cDeclCode += tab;
155 }
156 cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16",
157 stringTableName, str.length() + 1,
158 alComments.get(i))
159 + newLine;
160
161 if (i == 0) {
162 cInstCode = "/* StringTable */" + newLine;
163 }
164
165 cInstCode += tab + String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
166 if (i != al.size() - 1) {
167 cInstCode += commaNewLine;
168 }
169 }
170
171 decl = new CStructTypeDeclaration (
172 stringTable,
173 2,
174 cDeclCode,
175 true
176 );
177 declaList.add(decl);
178
179 instTable.put(stringTable, cInstCode);
180 }
181 }
182
183 public int add (String inputStr, Token token) {
184 int i;
185 int pos;
186
187 String str = inputStr;
188
189 //
190 // The input can be two types:
191 // "L\"Bootmode\"" or "Bootmode".
192 // We drop the L\" and \" for the first type.
193 if (str.startsWith("L\"") && str.endsWith("\"")) {
194 str = str.substring(2, str.length() - 1);
195 }
196 //
197 // Check if StringTable has this String already.
198 // If so, return the current pos.
199 //
200 for (i = 0, pos = 0; i < al.size(); i++) {
201 String s = al.get(i);;
202
203 if (str.equals(s)) {
204 return pos;
205 }
206 pos = s.length() + 1;
207 }
208
209 i = len;
210 //
211 // Include the NULL character at the end of String
212 //
213 len += str.length() + 1;
214 al.add(str);
215 alComments.add(token.getPrimaryKeyString());
216
217 return i;
218 }
219 }
220
221 /**
222 SizeTable
223
224 This class is used to store the Size information for
225 POINTER TYPE PCD entry in a PCD database.
226
227 **/
228 class SizeTable {
229 private ArrayList<ArrayList<Integer>> al;
230 private ArrayList<String> alComments;
231 private int len;
232 private String phase;
233
234 public SizeTable (String phase) {
235 al = new ArrayList<ArrayList<Integer>>();
236 alComments = new ArrayList<String>();
237 len = 0;
238 this.phase = phase;
239 }
240
241 public String getSizeMacro () {
242 return String.format(PcdDatabase.SizeTableSizeMacro, phase, getSize());
243 }
244
245 private int getSize() {
246 return len == 0 ? 1 : len;
247 }
248
249 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
250 final String name = "SizeTable";
251
252 CStructTypeDeclaration decl;
253 String cCode;
254
255 cCode = String.format(PcdDatabase.SizeTableDeclaration, phase);
256 decl = new CStructTypeDeclaration (
257 name,
258 2,
259 cCode,
260 true
261 );
262 declaList.add(decl);
263
264
265 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
266 instTable.put(name, cCode);
267 }
268
269 private ArrayList<String> getInstantiation () {
270 final String comma = ",";
271 ArrayList<String> Output = new ArrayList<String>();
272
273 Output.add("/* SizeTable */");
274 Output.add("{");
275 if (al.size() == 0) {
276 Output.add("\t0");
277 } else {
278 for (int index = 0; index < al.size(); index++) {
279 ArrayList<Integer> ial = al.get(index);
280
281 String str = "\t";
282
283 for (int index2 = 0; index2 < ial.size(); index2++) {
284 str += " " + ial.get(index2).toString();
285 if (index2 != ial.size() - 1) {
286 str += comma;
287 }
288 }
289
290 str += " /* " + alComments.get(index) + " */";
291
292 if (index != (al.size() - 1)) {
293 str += comma;
294 }
295
296 Output.add(str);
297
298 }
299 }
300 Output.add("}");
301
302 return Output;
303 }
304
305 public void add (Token token) {
306
307 //
308 // We only have size information for POINTER type PCD entry.
309 //
310 if (token.datumType != Token.DATUM_TYPE.POINTER) {
311 return;
312 }
313
314 ArrayList<Integer> ial = token.getPointerTypeSize();
315
316 len+= ial.size();
317
318 al.add(ial);
319 alComments.add(token.getPrimaryKeyString());
320
321 return;
322 }
323
324 }
325
326 /**
327 GuidTable
328
329 This class is used to store the GUIDs in a PCD database.
330 **/
331 class GuidTable {
332 private ArrayList<UUID> al;
333 private ArrayList<String> alComments;
334 private String phase;
335 private int len;
336 private int bodyLineNum;
337
338 public GuidTable (String phase) {
339 this.phase = phase;
340 al = new ArrayList<UUID>();
341 alComments = new ArrayList<String>();
342 len = 0;
343 bodyLineNum = 0;
344 }
345
346 public String getSizeMacro () {
347 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());
348 }
349
350 private int getSize () {
351 return (al.size() == 0)? 1 : al.size();
352 }
353
354 public String getExistanceMacro () {
355 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
356 }
357
358 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
359 final String name = "GuidTable";
360
361 CStructTypeDeclaration decl;
362 String cCode = "";
363
364 cCode += String.format(PcdDatabase.GuidTableDeclaration, phase);
365 decl = new CStructTypeDeclaration (
366 name,
367 4,
368 cCode,
369 true
370 );
371 declaList.add(decl);
372
373
374 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
375 instTable.put(name, cCode);
376 }
377
378 private String getUuidCString (UUID uuid) {
379 String[] guidStrArray;
380
381 guidStrArray =(uuid.toString()).split("-");
382
383 return String.format("{0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",
384 guidStrArray[0],
385 guidStrArray[1],
386 guidStrArray[2],
387 (guidStrArray[3].substring(0, 2)),
388 (guidStrArray[3].substring(2, 4)),
389 (guidStrArray[4].substring(0, 2)),
390 (guidStrArray[4].substring(2, 4)),
391 (guidStrArray[4].substring(4, 6)),
392 (guidStrArray[4].substring(6, 8)),
393 (guidStrArray[4].substring(8, 10)),
394 (guidStrArray[4].substring(10, 12))
395 );
396 }
397
398 private ArrayList<String> getInstantiation () {
399 ArrayList<String> Output = new ArrayList<String>();
400
401 Output.add("/* GuidTable */");
402 Output.add("{");
403
404 if (al.size() == 0) {
405 Output.add("\t" + getUuidCString(new UUID(0, 0)));
406 }
407
408 for (int i = 0; i < al.size(); i++) {
409 String str = "\t" + getUuidCString(al.get(i));
410
411 str += "/* " + alComments.get(i) + " */";
412 if (i != (al.size() - 1)) {
413 str += ",";
414 }
415 Output.add(str);
416 bodyLineNum++;
417
418 }
419 Output.add("}");
420
421 return Output;
422 }
423
424 public int add (UUID uuid, String name) {
425 //
426 // Check if GuidTable has this entry already.
427 // If so, return the GuidTable index.
428 //
429 for (int i = 0; i < al.size(); i++) {
430 if (al.get(i).compareTo(uuid) == 0) {
431 return i;
432 }
433 }
434
435 len++;
436 al.add(uuid);
437 alComments.add(name);
438
439 //
440 // Return the previous Table Index
441 //
442 return len - 1;
443 }
444
445 }
446
447 /**
448 SkuIdTable
449
450 This class is used to store the SKU IDs in a PCD database.
451
452 **/
453 class SkuIdTable {
454 private ArrayList<Integer[]> al;
455 private ArrayList<String> alComment;
456 private String phase;
457 private int len;
458
459 public SkuIdTable (String phase) {
460 this.phase = phase;
461 al = new ArrayList<Integer[]>();
462 alComment = new ArrayList<String>();
463 len = 0;
464 }
465
466 public String getSizeMacro () {
467 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());
468 }
469
470 private int getSize () {
471 return (len == 0)? 1 : len;
472 }
473
474 public String getExistanceMacro () {
475 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
476 }
477
478 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
479 final String name = "SkuIdTable";
480
481 CStructTypeDeclaration decl;
482 String cCode = "";
483
484 cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase);
485 decl = new CStructTypeDeclaration (
486 name,
487 1,
488 cCode,
489 true
490 );
491 declaList.add(decl);
492
493
494 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
495 instTable.put(name, cCode);
496
497 //
498 // SystemSkuId is in PEI phase PCD Database
499 //
500 if (phase.equalsIgnoreCase("PEI")) {
501 decl = new CStructTypeDeclaration (
502 "SystemSkuId",
503 1,
504 String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),
505 true
506 );
507 declaList.add(decl);
508
509 instTable.put("SystemSkuId", "0");
510 }
511
512 }
513
514 private ArrayList<String> getInstantiation () {
515 ArrayList<String> Output = new ArrayList<String> ();
516
517 Output.add("/* SkuIdTable */");
518 Output.add("{");
519
520 if (al.size() == 0) {
521 Output.add("\t0");
522 }
523
524 for (int index = 0; index < al.size(); index++) {
525 String str;
526
527 str = "/* " + alComment.get(index) + "*/ ";
528 str += "/* MaxSku */ ";
529
530
531 Integer[] ia = al.get(index);
532
533 str += "\t" + ia[0].toString() + ", ";
534 for (int index2 = 1; index2 < ia.length; index2++) {
535 str += ia[index2].toString();
536 if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {
537 str += ", ";
538 }
539 }
540
541 Output.add(str);
542
543 }
544
545 Output.add("}");
546
547 return Output;
548 }
549
550 public int add (Token token) {
551
552 int index;
553 int pos;
554
555 //
556 // Check if this SKU_ID Array is already in the table
557 //
558 pos = 0;
559 for (Object o: al) {
560 Integer [] s = (Integer[]) o;
561 boolean different = false;
562 if (s[0] == token.getSkuIdCount()) {
563 for (index = 1; index < s.length; index++) {
564 if (s[index] != token.skuData.get(index-1).id) {
565 different = true;
566 break;
567 }
568 }
569 } else {
570 different = true;
571 }
572 if (different) {
573 pos += s[0] + 1;
574 } else {
575 return pos;
576 }
577 }
578
579 Integer [] skuIds = new Integer[token.skuData.size() + 1];
580 skuIds[0] = new Integer(token.skuData.size());
581 for (index = 1; index < skuIds.length; index++) {
582 skuIds[index] = new Integer(token.skuData.get(index - 1).id);
583 }
584
585 index = len;
586
587 len += skuIds.length;
588 al.add(skuIds);
589 alComment.add(token.getPrimaryKeyString());
590
591 return index;
592 }
593
594 }
595
596 class LocalTokenNumberTable {
597 private ArrayList<String> al;
598 private ArrayList<String> alComment;
599 private String phase;
600 private int len;
601
602 public LocalTokenNumberTable (String phase) {
603 this.phase = phase;
604 al = new ArrayList<String>();
605 alComment = new ArrayList<String>();
606
607 len = 0;
608 }
609
610 public String getSizeMacro () {
611 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())
612 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());
613 }
614
615 public int getSize () {
616 return (al.size() == 0)? 1 : al.size();
617 }
618
619 public String getExistanceMacro () {
620 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
621 }
622
623 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
624 final String name = "LocalTokenNumberTable";
625
626 CStructTypeDeclaration decl;
627 String cCode = "";
628
629 cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
630 decl = new CStructTypeDeclaration (
631 name,
632 4,
633 cCode,
634 true
635 );
636 declaList.add(decl);
637
638 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
639 instTable.put(name, cCode);
640 }
641
642 private ArrayList<String> getInstantiation () {
643 ArrayList<String> output = new ArrayList<String>();
644
645 output.add("/* LocalTokenNumberTable */");
646 output.add("{");
647
648 if (al.size() == 0) {
649 output.add("\t0");
650 }
651
652 for (int index = 0; index < al.size(); index++) {
653 String str;
654
655 str = "\t" + (String)al.get(index);
656
657 str += " /* " + alComment.get(index) + " */ ";
658
659
660 if (index != (al.size() - 1)) {
661 str += ",";
662 }
663
664 output.add(str);
665
666 }
667
668 output.add("}");
669
670 return output;
671 }
672
673 public int add (Token token) {
674 int index = len;
675 String str;
676
677 len++;
678
679 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());
680
681 if (token.isUnicodeStringType()) {
682 str += " | PCD_TYPE_STRING";
683 }
684
685 if (token.isSkuEnable()) {
686 str += " | PCD_TYPE_SKU_ENABLED";
687 }
688
689 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
690 str += " | PCD_TYPE_HII";
691 }
692
693 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
694 str += " | PCD_TYPE_VPD";
695 }
696
697 switch (token.datumType) {
698 case UINT8:
699 case BOOLEAN:
700 str += " | PCD_DATUM_TYPE_UINT8";
701 break;
702 case UINT16:
703 str += " | PCD_DATUM_TYPE_UINT16";
704 break;
705 case UINT32:
706 str += " | PCD_DATUM_TYPE_UINT32";
707 break;
708 case UINT64:
709 str += " | PCD_DATUM_TYPE_UINT64";
710 break;
711 case POINTER:
712 str += " | PCD_DATUM_TYPE_POINTER";
713 break;
714 }
715
716 al.add(str);
717 alComment.add(token.getPrimaryKeyString());
718
719 return index;
720 }
721 }
722
723 /**
724 ExMapTable
725
726 This class is used to store the table of mapping information
727 between DynamicEX ID pair(Guid, TokenNumber) and
728 the local token number assigned by PcdDatabase class.
729 **/
730 class ExMapTable {
731
732 /**
733 ExTriplet
734
735 This class is used to store the mapping information
736 between DynamicEX ID pair(Guid, TokenNumber) and
737 the local token number assigned by PcdDatabase class.
738 **/
739 class ExTriplet {
740 public Integer guidTableIdx;
741 public Long exTokenNumber;
742 public Long localTokenIdx;
743
744 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {
745 this.guidTableIdx = new Integer(guidTableIdx);
746 this.exTokenNumber = new Long(exTokenNumber);
747 this.localTokenIdx = new Long(localTokenIdx);
748 }
749 }
750
751 private ArrayList<ExTriplet> al;
752 private Map<ExTriplet, String> alComment;
753 private String phase;
754 private int len;
755 private int bodyLineNum;
756
757 public ExMapTable (String phase) {
758 this.phase = phase;
759 al = new ArrayList<ExTriplet>();
760 alComment = new HashMap<ExTriplet, String>();
761 bodyLineNum = 0;
762 len = 0;
763 }
764
765 public String getSizeMacro () {
766 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())
767 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());
768 }
769
770 public String getExistanceMacro () {
771 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
772 }
773
774 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
775 final String exMapTableName = "ExMapTable";
776
777 sortTable();
778
779 CStructTypeDeclaration decl;
780 String cCode = "";
781
782 cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase);
783 decl = new CStructTypeDeclaration (
784 exMapTableName,
785 4,
786 cCode,
787 true
788 );
789 declaList.add(decl);
790
791
792 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
793 instTable.put(exMapTableName, cCode);
794 }
795
796 private ArrayList<String> getInstantiation () {
797 ArrayList<String> Output = new ArrayList<String>();
798
799 Output.add("/* ExMapTable */");
800 Output.add("{");
801 if (al.size() == 0) {
802 Output.add("\t{0, 0, 0}");
803 }
804
805 int index;
806 for (index = 0; index < al.size(); index++) {
807 String str;
808
809 ExTriplet e = (ExTriplet)al.get(index);
810
811 str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";
812 str += e.localTokenIdx.toString() + ", ";
813 str += e.guidTableIdx.toString();
814
815 str += "}" + " /* " + alComment.get(e) + " */" ;
816
817 if (index != al.size() - 1) {
818 str += ",";
819 }
820
821 Output.add(str);
822 bodyLineNum++;
823
824 }
825
826 Output.add("}");
827
828 return Output;
829 }
830
831 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {
832 int index = len;
833
834 len++;
835 ExTriplet et = new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx);
836
837 al.add(et);
838 alComment.put(et, name);
839
840 return index;
841 }
842
843 private int getTableLen () {
844 return al.size() == 0 ? 1 : al.size();
845 }
846
847 //
848 // To simplify the algorithm for GetNextToken and GetNextTokenSpace in
849 // PCD PEIM/Driver, we need to sort the ExMapTable according to the
850 // following order:
851 // 1) ExGuid
852 // 2) ExTokenNumber
853 //
854 class ExTripletComp implements Comparator<ExTriplet> {
855 public int compare (ExTriplet a, ExTriplet b) {
856 if (a.guidTableIdx == b.guidTableIdx ) {
857 //
858 // exTokenNumber is long, we can't use simple substraction.
859 //
860 if (a.exTokenNumber > b.exTokenNumber) {
861 return 1;
862 } else if (a.exTokenNumber == b.exTokenNumber) {
863 return 0;
864 } else {
865 return -1;
866 }
867 }
868
869 return a.guidTableIdx - b.guidTableIdx;
870 }
871 }
872
873 private void sortTable () {
874 java.util.Comparator<ExTriplet> comparator = new ExTripletComp();
875 java.util.Collections.sort(al, comparator);
876 }
877 }
878
879 /**
880 PcdDatabase
881
882 This class is used to generate C code for Autogen.h and Autogen.c of
883 a PCD service DXE driver and PCD service PEIM.
884 **/
885 public class PcdDatabase {
886
887 private final static int SkuHeadAlignmentSize = 4;
888 private final String newLine = "\r\n";
889 private final String commaNewLine = ",\r\n";
890 private final String tab = "\t";
891 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
892 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
893 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
894 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
895 public final static String SizeTableDeclaration = "SIZE_INFO SizeTable[%s_SIZE_TABLE_SIZE];\r\n";
896 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
897
898
899 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
900 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";
901 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";
902 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";
903 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
904 public final static String SizeTableSizeMacro = "#define %s_SIZE_TABLE_SIZE %d\r\n";
905 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";
906 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";
907
908
909 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
910 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";
911 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";
912 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";
913 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";
914
915 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
916 public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";
917 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";
918
919 private final static String skuDataTableTemplate = "SkuDataTable";
920
921
922 private StringTable stringTable;
923 private GuidTable guidTable;
924 private LocalTokenNumberTable localTokenNumberTable;
925 private SkuIdTable skuIdTable;
926 private SizeTable sizeTable;
927 private ExMapTable exMapTable;
928
929 private ArrayList<Token> alTokens;
930 private String phase;
931 private int assignedTokenNumber;
932
933 //
934 // Use two class global variable to store
935 // temperary
936 //
937 private String privateGlobalName;
938 private String privateGlobalCCode;
939 //
940 // After Major changes done to the PCD
941 // database generation class PcdDatabase
942 // Please increment the version and please
943 // also update the version number in PCD
944 // service PEIM and DXE driver accordingly.
945 //
946 private final int version = 2;
947
948 private String hString;
949 private String cString;
950
951 /**
952 Constructor for PcdDatabase class.
953
954 <p>We have two PCD dynamic(ex) database for the Framework implementation. One
955 for PEI phase and the other for DXE phase. </p>
956
957 @param alTokens A ArrayList of Dynamic(EX) PCD entry.
958 @param exePhase The phase to generate PCD database for: valid input
959 is "PEI" or "DXE".
960 @param startLen The starting Local Token Number for the PCD database. For
961 PEI phase, the starting Local Token Number starts from 0.
962 For DXE phase, the starting Local Token Number starts
963 from the total number of PCD entry of PEI phase.
964 @return void
965 **/
966 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {
967 phase = exePhase;
968
969 stringTable = new StringTable(phase);
970 guidTable = new GuidTable(phase);
971 localTokenNumberTable = new LocalTokenNumberTable(phase);
972 skuIdTable = new SkuIdTable(phase);
973 sizeTable = new SizeTable(phase);
974 exMapTable = new ExMapTable(phase);
975
976 //
977 // Local token number 0 is reserved for INVALID_TOKEN_NUMBER.
978 // So we will increment 1 for the startLen passed from the
979 // constructor.
980 //
981 assignedTokenNumber = startLen + 1;
982 this.alTokens = alTokens;
983 }
984
985 private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {
986 for (int i = 0; i < alTokens.size(); i++) {
987 Token t = (Token)alTokens.get(i);
988 if (t.isDynamicEx()) {
989 exTokens.add(t);
990 } else {
991 nexTokens.add(t);
992 }
993 }
994
995 return;
996 }
997
998 private int getDataTypeAlignmentSize (Token token) {
999 switch (token.datumType) {
1000 case UINT8:
1001 return 1;
1002 case UINT16:
1003 return 2;
1004 case UINT32:
1005 return 4;
1006 case UINT64:
1007 return 8;
1008 case POINTER:
1009 return 1;
1010 case BOOLEAN:
1011 return 1;
1012 default:
1013 return 1;
1014 }
1015 }
1016
1017 private int getHiiPtrTypeAlignmentSize(Token token) {
1018 switch (token.datumType) {
1019 case UINT8:
1020 return 1;
1021 case UINT16:
1022 return 2;
1023 case UINT32:
1024 return 4;
1025 case UINT64:
1026 return 8;
1027 case POINTER:
1028 if (token.isHiiEnable()) {
1029 if (token.isHiiDefaultValueUnicodeStringType()) {
1030 return 2;
1031 }
1032 }
1033 return 1;
1034 case BOOLEAN:
1035 return 1;
1036 default:
1037 return 1;
1038 }
1039 }
1040
1041 private int getAlignmentSize (Token token) {
1042 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
1043 return 2;
1044 }
1045
1046 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
1047 return 4;
1048 }
1049
1050 if (token.isUnicodeStringType()) {
1051 return 2;
1052 }
1053
1054 return getDataTypeAlignmentSize(token);
1055 }
1056
1057 public String getCString () {
1058 return cString;
1059 }
1060
1061 public String getHString () {
1062 return hString;
1063 }
1064
1065 private void genCodeWorker(Token t,
1066 ArrayList<CStructTypeDeclaration> declaList,
1067 HashMap<String, String> instTable, String phase)
1068 throws EntityException {
1069
1070 CStructTypeDeclaration decl;
1071
1072 //
1073 // Insert SKU_HEAD if isSkuEnable is true
1074 //
1075 if (t.isSkuEnable()) {
1076 int tableIdx;
1077 tableIdx = skuIdTable.add(t);
1078 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),
1079 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);
1080 declaList.add(decl);
1081 instTable.put(t.getPrimaryKeyString(),
1082 getSkuEnabledTypeInstantiaion(t, tableIdx));
1083 }
1084
1085 //
1086 // Insert PCD_ENTRY declaration and instantiation
1087 //
1088 getCDeclarationString(t);
1089
1090 decl = new CStructTypeDeclaration(privateGlobalName,
1091 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());
1092 declaList.add(decl);
1093
1094 if (t.hasDefaultValue()) {
1095 instTable.put(privateGlobalName,
1096 getTypeInstantiation(t, declaList, instTable, phase)
1097 );
1098 }
1099
1100 }
1101
1102 private void ProcessTokens (List<Token> tokens,
1103 ArrayList<CStructTypeDeclaration> cStructDeclList,
1104 HashMap<String, String> cStructInstTable,
1105 String phase
1106 )
1107 throws EntityException {
1108
1109 for (int idx = 0; idx < tokens.size(); idx++) {
1110 Token t = tokens.get(idx);
1111
1112 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);
1113
1114 sizeTable.add(t);
1115 localTokenNumberTable.add(t);
1116 t.tokenNumber = assignedTokenNumber++;
1117
1118 //
1119 // Add a mapping if this dynamic PCD entry is a EX type
1120 //
1121 if (t.isDynamicEx()) {
1122 exMapTable.add((int)t.tokenNumber,
1123 t.dynamicExTokenNumber,
1124 guidTable.add(translateSchemaStringToUUID(t.tokenSpaceName), t.getPrimaryKeyString()),
1125 t.getPrimaryKeyString()
1126 );
1127 }
1128 }
1129
1130 }
1131
1132 public void genCode () throws EntityException {
1133
1134 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();
1135 HashMap<String, String> cStructInstTable = new HashMap<String, String>();
1136
1137 List<Token> nexTokens = new ArrayList<Token> ();
1138 List<Token> exTokens = new ArrayList<Token> ();
1139
1140 getNonExAndExTokens (alTokens, nexTokens, exTokens);
1141
1142 //
1143 // We have to process Non-Ex type PCD entry first. The reason is
1144 // that our optimization assumes that the Token Number of Non-Ex
1145 // PCD entry start from 1 (for PEI phase) and grows continously upwards.
1146 //
1147 // EX type token number starts from the last Non-EX PCD entry and
1148 // grows continously upwards.
1149 //
1150 ProcessTokens (nexTokens, cStructDeclList, cStructInstTable, phase);
1151 ProcessTokens (exTokens, cStructDeclList, cStructInstTable, phase);
1152
1153 stringTable.genCode(cStructDeclList, cStructInstTable);
1154 skuIdTable.genCode(cStructDeclList, cStructInstTable, phase);
1155 exMapTable.genCode(cStructDeclList, cStructInstTable, phase);
1156 localTokenNumberTable.genCode(cStructDeclList, cStructInstTable, phase);
1157 sizeTable.genCode(cStructDeclList, cStructInstTable, phase);
1158 guidTable.genCode(cStructDeclList, cStructInstTable, phase);
1159
1160 hString = genCMacroCode ();
1161
1162 HashMap <String, String> result;
1163
1164 result = genCStructCode(cStructDeclList,
1165 cStructInstTable,
1166 phase
1167 );
1168
1169 hString += result.get("initDeclStr");
1170 hString += result.get("uninitDeclStr");
1171
1172 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
1173
1174 cString = newLine + newLine + result.get("initInstStr");
1175
1176 }
1177
1178 private String genCMacroCode () {
1179 String macroStr = "";
1180
1181 //
1182 // Generate size info Macro for all Tables
1183 //
1184 macroStr += guidTable.getSizeMacro();
1185 macroStr += stringTable.getSizeMacro();
1186 macroStr += skuIdTable.getSizeMacro();
1187 macroStr += localTokenNumberTable.getSizeMacro();
1188 macroStr += exMapTable.getSizeMacro();
1189 macroStr += sizeTable.getSizeMacro();
1190
1191 //
1192 // Generate existance info Macro for all Tables
1193 //
1194 macroStr += guidTable.getExistanceMacro();
1195 macroStr += stringTable.getExistanceMacro();
1196 macroStr += skuIdTable.getExistanceMacro();
1197 macroStr += localTokenNumberTable.getExistanceMacro();
1198 macroStr += exMapTable.getExistanceMacro();
1199
1200 macroStr += newLine;
1201
1202 return macroStr;
1203 }
1204
1205 private HashMap <String, String> genCStructCode(
1206 ArrayList<CStructTypeDeclaration> declaList,
1207 HashMap<String, String> instTable,
1208 String phase
1209 ) {
1210
1211 int i;
1212 HashMap <String, String> result = new HashMap<String, String>();
1213 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();
1214 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();
1215 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();
1216
1217 //
1218 // Initialize the storage for each alignment
1219 //
1220 for (i = 8; i > 0; i>>=1) {
1221 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());
1222 alignmentInitInst.put(new Integer(i), new ArrayList<String>());
1223 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());
1224 }
1225
1226 String initDeclStr = "typedef struct {" + newLine;
1227 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;
1228 String uninitDeclStr = "typedef struct {" + newLine;
1229
1230 //
1231 // Sort all C declaration and instantiation base on Alignment Size
1232 //
1233 for (Object d : declaList) {
1234 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;
1235
1236 if (decl.initTable) {
1237 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
1238 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));
1239 } else {
1240 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
1241 }
1242 }
1243
1244 //
1245 // Generate code for every alignment size
1246 //
1247 boolean uinitDatabaseEmpty = true;
1248 for (int align = 8; align > 0; align >>= 1) {
1249 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));
1250 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));
1251 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {
1252 initDeclStr += tab + declaListBasedOnAlignment.get(i);
1253 initInstStr += tab + instListBasedOnAlignment.get(i);
1254
1255 //
1256 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE
1257 // has a least one data memember with alignment size of 1. So we can
1258 // remove the last "," in the C structure instantiation string. Luckily,
1259 // this is true as both data structure has SKUID_TABLE anyway.
1260 //
1261 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {
1262 initInstStr += newLine;
1263 } else {
1264 initInstStr += commaNewLine;
1265 }
1266 }
1267
1268 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));
1269
1270 if (declaListBasedOnAlignment.size() != 0) {
1271 uinitDatabaseEmpty = false;
1272 }
1273
1274 for (Object d : declaListBasedOnAlignment) {
1275 String s = (String)d;
1276 uninitDeclStr += tab + s;
1277 }
1278 }
1279
1280 if (uinitDatabaseEmpty) {
1281 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");
1282 }
1283
1284 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;
1285 initInstStr += "};" + newLine;
1286 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;
1287
1288 result.put("initDeclStr", initDeclStr);
1289 result.put("initInstStr", initInstStr);
1290 result.put("uninitDeclStr", uninitDeclStr);
1291
1292 return result;
1293 }
1294
1295 public static String genInstantiationStr (ArrayList<String> alStr) {
1296 String str = "";
1297 for (int i = 0; i< alStr.size(); i++) {
1298 if (i != 0) {
1299 str += "\t";
1300 }
1301 str += alStr.get(i);
1302 if (i != alStr.size() - 1) {
1303 str += "\r\n";
1304 }
1305 }
1306
1307 return str;
1308 }
1309
1310 private String getSkuEnabledTypeDeclaration (Token token) {
1311 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());
1312 }
1313
1314 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
1315
1316 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
1317 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());
1318 }
1319
1320 private String getDataTypeInstantiationForVariableDefault (Token token, String cName, int skuId) {
1321 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);
1322 }
1323
1324 private String getCType (Token t)
1325 throws EntityException {
1326
1327 if (t.isHiiEnable()) {
1328 return "VARIABLE_HEAD";
1329 }
1330
1331 if (t.isVpdEnable()) {
1332 return "VPD_HEAD";
1333 }
1334
1335 if (t.isUnicodeStringType()) {
1336 return "STRING_HEAD";
1337 }
1338
1339 switch (t.datumType) {
1340 case UINT64:
1341 return "UINT64";
1342 case UINT32:
1343 return "UINT32";
1344 case UINT16:
1345 return "UINT16";
1346 case UINT8:
1347 return "UINT8";
1348 case BOOLEAN:
1349 return "BOOLEAN";
1350 case POINTER:
1351 return "UINT8";
1352 default:
1353 throw new EntityException("Unknown type in getDataTypeCDeclaration");
1354 }
1355 }
1356
1357 //
1358 // privateGlobalName and privateGlobalCCode is used to pass output to caller of getCDeclarationString
1359 //
1360 private void getCDeclarationString(Token t)
1361 throws EntityException {
1362
1363 if (t.isSkuEnable()) {
1364 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);
1365 } else {
1366 privateGlobalName = t.getPrimaryKeyString();
1367 }
1368
1369 String type = getCType(t);
1370 if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable()) && (!t.isUnicodeStringType())) {
1371 int bufferSize;
1372 if (t.isASCIIStringType()) {
1373 //
1374 // Build tool will add a NULL string at the end of the ASCII string
1375 //
1376 bufferSize = t.datumSize + 1;
1377 } else {
1378 bufferSize = t.datumSize;
1379 }
1380 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);
1381 } else {
1382 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());
1383 }
1384 }
1385
1386 private String getDataTypeDeclarationForVariableDefault (Token token, String cName, int skuId)
1387 throws EntityException {
1388
1389 String typeStr;
1390
1391 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1392 typeStr = "UINT8";
1393 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1394 typeStr = "UINT16";
1395 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1396 typeStr = "UINT32";
1397 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1398 typeStr = "UINT64";
1399 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1400 typeStr = "BOOLEAN";
1401 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1402 int size;
1403 if (token.isHiiDefaultValueUnicodeStringType()) {
1404 typeStr = "UINT16";
1405 //
1406 // Include the NULL charactor
1407 //
1408 size = token.datumSize / 2 + 1;
1409 } else {
1410 typeStr = "UINT8";
1411 if (token.isHiiDefaultValueASCIIStringType()) {
1412 //
1413 // Include the NULL charactor
1414 //
1415 size = token.datumSize + 1;
1416 } else {
1417 size = token.datumSize;
1418 }
1419 }
1420 return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);
1421 } else {
1422 throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");
1423 }
1424
1425 return String.format("%-20s%s;\r\n", typeStr, cName);
1426 }
1427
1428 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {
1429
1430 int i;
1431
1432 String s;
1433 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;
1434 s += tab + "{" + newLine;
1435
1436 for (i = 0; i < t.skuData.size(); i++) {
1437 if (t.isUnicodeStringType()) {
1438 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));
1439 } else if (t.isHiiEnable()) {
1440 /* VPD_HEAD definition
1441 typedef struct {
1442 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.
1443 UINT16 StringIndex; // Offset in String Table in units of UINT16.
1444 UINT16 Offset; // Offset in Variable
1445 UINT16 DefaultValueOffset; // Offset of the Default Value
1446 } VARIABLE_HEAD ;
1447 */
1448 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i);
1449
1450 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),
1451 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),
1452 t.skuData.get(i).value.variableOffset,
1453 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)
1454 );
1455 //
1456 // We need to support the default value, so we add the declaration and
1457 // the instantiation for the default value.
1458 //
1459 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,
1460 getHiiPtrTypeAlignmentSize(t),
1461 getDataTypeDeclarationForVariableDefault(t, variableDefaultName, i),
1462 true
1463 );
1464 declaList.add(decl);
1465 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault (t, variableDefaultName, i));
1466 } else if (t.isVpdEnable()) {
1467 /* typedef struct {
1468 UINT32 Offset;
1469 } VPD_HEAD;
1470 */
1471 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);
1472 } else {
1473 if (t.isByteStreamType()) {
1474 //
1475 // Byte stream type input has their own "{" "}", so we won't help to insert.
1476 //
1477 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);
1478 } else {
1479 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);
1480 }
1481 }
1482
1483 if (i != t.skuData.size() - 1) {
1484 s += commaNewLine;
1485 } else {
1486 s += newLine;
1487 }
1488
1489 }
1490
1491 s += tab + "}";
1492
1493 return s;
1494 }
1495
1496 public static String getPcdDatabaseCommonDefinitions ()
1497 throws EntityException {
1498
1499 String retStr = "";
1500 try {
1501 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1502 "Tools" + File.separator +
1503 "Conf" + File.separator +
1504 "Pcd" + File.separator +
1505 "PcdDatabaseCommonDefinitions.sample");
1506 FileReader reader = new FileReader(file);
1507 BufferedReader in = new BufferedReader(reader);
1508 String str;
1509 while ((str = in.readLine()) != null) {
1510 retStr = retStr +"\r\n" + str;
1511 }
1512 } catch (Exception ex) {
1513 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1514 }
1515
1516 return retStr;
1517 }
1518
1519 public static String getPcdDxeDatabaseDefinitions ()
1520 throws EntityException {
1521
1522 String retStr = "";
1523 try {
1524 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1525 "Tools" + File.separator +
1526 "Conf" + File.separator +
1527 "Pcd" + File.separator +
1528 "PcdDatabaseDxeDefinitions.sample");
1529 FileReader reader = new FileReader(file);
1530 BufferedReader in = new BufferedReader(reader);
1531 String str;
1532 while ((str = in.readLine()) != null) {
1533 retStr = retStr +"\r\n" + str;
1534 }
1535 } catch (Exception ex) {
1536 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1537 }
1538
1539 return retStr;
1540 }
1541
1542 public static String getPcdPeiDatabaseDefinitions ()
1543 throws EntityException {
1544
1545 String retStr = "";
1546 try {
1547 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1548 "Tools" + File.separator +
1549 "Conf" + File.separator +
1550 "Pcd" + File.separator +
1551 "PcdDatabasePeiDefinitions.sample");
1552 FileReader reader = new FileReader(file);
1553 BufferedReader in = new BufferedReader(reader);
1554 String str;
1555 while ((str = in.readLine()) != null) {
1556 retStr = retStr +"\r\n" + str;
1557 }
1558 } catch (Exception ex) {
1559 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1560 }
1561
1562 return retStr;
1563 }
1564
1565 /**
1566 Translate the schema string to UUID instance.
1567
1568 In schema, the string of UUID is defined as following two types string:
1569 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
1570 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
1571
1572 2) GuidNamingConvention: pattern =
1573 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
1574
1575 This function will convert string and create uuid instance.
1576
1577 @param uuidString UUID string in XML file
1578
1579 @return UUID UUID instance
1580 **/
1581 private UUID translateSchemaStringToUUID(String uuidString)
1582 throws EntityException {
1583 String temp;
1584 String[] splitStringArray;
1585 int index;
1586 int chIndex;
1587 int chLen;
1588
1589 if (uuidString == null) {
1590 return null;
1591 }
1592
1593 if (uuidString.length() == 0) {
1594 return null;
1595 }
1596
1597 if (uuidString.equals("0") ||
1598 uuidString.equalsIgnoreCase("0x0")) {
1599 return new UUID(0, 0);
1600 }
1601
1602 uuidString = uuidString.replaceAll("\\{", "");
1603 uuidString = uuidString.replaceAll("\\}", "");
1604
1605 //
1606 // If the UUID schema string is GuidArrayType type then need translate
1607 // to GuidNamingConvention type at first.
1608 //
1609 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
1610 splitStringArray = uuidString.split("," );
1611 if (splitStringArray.length != 11) {
1612 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);
1613 }
1614
1615 //
1616 // Remove blank space from these string and remove header string "0x"
1617 //
1618 for (index = 0; index < 11; index ++) {
1619 splitStringArray[index] = splitStringArray[index].trim();
1620 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
1621 }
1622
1623 //
1624 // Add heading '0' to normalize the string length
1625 //
1626 for (index = 3; index < 11; index ++) {
1627 chLen = splitStringArray[index].length();
1628 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
1629 splitStringArray[index] = "0" + splitStringArray[index];
1630 }
1631 }
1632
1633 //
1634 // construct the final GuidNamingConvention string
1635 //
1636 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
1637 splitStringArray[0],
1638 splitStringArray[1],
1639 splitStringArray[2],
1640 splitStringArray[3],
1641 splitStringArray[4],
1642 splitStringArray[5],
1643 splitStringArray[6],
1644 splitStringArray[7],
1645 splitStringArray[8],
1646 splitStringArray[9],
1647 splitStringArray[10]);
1648 uuidString = temp;
1649 }
1650
1651 return UUID.fromString(uuidString);
1652 }
1653 }