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