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