blob: d848d1f561df629458ecec41af13d9da5fa0baa2 [file] [log] [blame]
/** @file
PcdDatabase class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.pcd.action;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.tianocore.pcd.entity.DynamicTokenValue;
import org.tianocore.pcd.entity.Token;
import org.tianocore.pcd.exception.EntityException;
/**
CStructTypeDeclaration
This class is used to store the declaration string, such as
"UINT32 PcdPlatformFlashBaseAddress", of
each memember in the C structure, which is a standard C language
feature used to implement a simple and efficient database for
dynamic(ex) type PCD entry.
**/
class CStructTypeDeclaration {
String key;
int alignmentSize;
String cCode;
boolean initTable;
public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {
this.key = key;
this.alignmentSize = alignmentSize;
this.cCode = cCode;
this.initTable = initTable;
}
}
/**
StringTable
This class is used to store the String in a PCD database.
**/
class StringTable {
class UnicodeString {
//
// In Schema, we define VariableName in DynamicPcdBuildDefinitions in FPD
// file to be HexWordArrayType. For example, Unicode String L"Setup" is
// <VariableName>0x0053 0x0065 0x0074 0x0075 0x0070</VariableName>.
// We use raw to differentiate if the String is in form of L"Setup" (raw is false) or
// in form of {0x0053, 0x0065, 0x0074, 0x0075, 0x0070}
//
// This str is the string that can be pasted directly into the C structure.
// For example, this str can be two forms:
//
// L"Setup",
// {0x0053, 0065, 0x0074, 0x0075, 0x0070, 0x0000}, //This is another form of L"Setup"
//
public String str;
//
// This len includes the NULL character at the end of the String.
//
public int len;
public UnicodeString (String str, int len) {
this.str = str;
this.len = len;
}
}
private ArrayList<UnicodeString> al;
private ArrayList<String> alComments;
private String phase;
int stringTableCharNum;
public StringTable (String phase) {
this.phase = phase;
al = new ArrayList<UnicodeString>();
alComments = new ArrayList<String>();
stringTableCharNum = 0;
}
public String getSizeMacro () {
return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());
}
private int getSize () {
//
// We have at least one Unicode Character in the table.
//
return stringTableCharNum == 0 ? 1 : stringTableCharNum;
}
public String getExistanceMacro () {
return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
}
public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {
final String stringTable = "StringTable";
final String tab = "\t";
final String newLine = "\r\n";
final String commaNewLine = ",\r\n";
CStructTypeDeclaration decl;
String cDeclCode = "";
String cInstCode = "";
//
// If we have a empty StringTable
//
if (al.size() == 0) {
cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine;
decl = new CStructTypeDeclaration (
stringTable,
2,
cDeclCode,
true
);
declaList.add(decl);
cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";
instTable.put(stringTable, cInstCode);
} else {
//
// If there is any String in the StringTable
//
for (int i = 0; i < al.size(); i++) {
UnicodeString uStr = al.get(i);
String stringTableName;
if (i == 0) {
//
// StringTable is a well-known name in the PCD DXE driver
//
stringTableName = stringTable;
} else {
stringTableName = String.format("%s_%d", stringTable, i);
cDeclCode += tab;
}
cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16",
stringTableName, uStr.len,
alComments.get(i))
+ newLine;
if (i == 0) {
cInstCode = "/* StringTable */" + newLine;
}
cInstCode += tab + String.format("%s /* %s */", uStr.str, alComments.get(i));
if (i != al.size() - 1) {
cInstCode += commaNewLine;
}
}
decl = new CStructTypeDeclaration (
stringTable,
2,
cDeclCode,
true
);
declaList.add(decl);
instTable.put(stringTable, cInstCode);
}
}
public int add (List inputStr, Token token) {
String str;
str = "{";
for (int i = 0; i < inputStr.size(); i++) {
str += " " + inputStr.get(i) + ",";
}
str += " 0x0000";
str += "}";
//
// This is a raw Unicode String
//
return addToTable (str, inputStr.size() + 1, token);
}
public int add (String inputStr, Token token) {
int len;
String str = inputStr;
//
// The input can be two types:
// "L\"Bootmode\"" or "Bootmode".
// We drop the L\" and \" for the first type.
if (str.startsWith("L\"") && str.endsWith("\"")) {
//
// Substract the character of "L", """, """.
// and add in the NULL character. So it is 2.
//
len = str.length() - 2;
} else {
//
// Include the NULL character.
//
len = str.length() + 1;
str = "L\"" + str + "\"";
}
//
// After processing, this is L"A String Sample" type of string.
//
return addToTable (str, len, token);
}
private int addToTable (String inputStr, int len, Token token) {
int i;
int pos;
//
// Check if StringTable has this String already.
// If so, return the current pos.
//
for (i = 0, pos = 0; i < al.size(); i++) {
UnicodeString s = al.get(i);;
if (inputStr.equals(s.str)) {
return pos;
}
pos += s.len;
}
i = stringTableCharNum;
//
// Include the NULL character at the end of String
//
stringTableCharNum += len;
al.add(new UnicodeString(inputStr, len));
alComments.add(token.getPrimaryKeyString());
return i;
}
}
/**
SizeTable
This class is used to store the Size information for
POINTER TYPE PCD entry in a PCD database.
**/
class SizeTable {
private ArrayList<ArrayList<Integer>> al;
private ArrayList<String> alComments;
private int len;
private String phase;
public SizeTable (String phase) {
al = new ArrayList<ArrayList<Integer>>();
alComments = new ArrayList<String>();
len = 0;
this.phase = phase;
}
public String getSizeMacro () {
return String.format(PcdDatabase.SizeTableSizeMacro, phase, getSize());
}
private int getSize() {
return len == 0 ? 1 : len;
}
public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
final String name = "SizeTable";
CStructTypeDeclaration decl;
String cCode;
cCode = String.format(PcdDatabase.SizeTableDeclaration, phase);
decl = new CStructTypeDeclaration (
name,
2,
cCode,
true
);
declaList.add(decl);
cCode = PcdDatabase.genInstantiationStr(getInstantiation());
instTable.put(name, cCode);
}
private ArrayList<String> getInstantiation () {
final String comma = ",";
ArrayList<String> Output = new ArrayList<String>();
Output.add("/* SizeTable */");
Output.add("{");
if (al.size() == 0) {
Output.add("\t0");
} else {
for (int index = 0; index < al.size(); index++) {
ArrayList<Integer> ial = al.get(index);
String str = "\t";
for (int index2 = 0; index2 < ial.size(); index2++) {
str += " " + ial.get(index2).toString();
if (index2 != ial.size() - 1) {
str += comma;
}
}
str += " /* " + alComments.get(index) + " */";
if (index != (al.size() - 1)) {
str += comma;
}
Output.add(str);
}
}
Output.add("}");
return Output;
}
public void add (Token token) {
//
// We only have size information for POINTER type PCD entry.
//
if (token.datumType != Token.DATUM_TYPE.POINTER) {
return;
}
ArrayList<Integer> ial = token.getPointerTypeSize();
len+= ial.size();
al.add(ial);
alComments.add(token.getPrimaryKeyString());
return;
}
}
/**
GuidTable
This class is used to store the GUIDs in a PCD database.
**/
class GuidTable {
private ArrayList<UUID> al;
private ArrayList<String> alComments;
private String phase;
private int len;
private int bodyLineNum;
public GuidTable (String phase) {
this.phase = phase;
al = new ArrayList<UUID>();
alComments = new ArrayList<String>();
len = 0;
bodyLineNum = 0;
}
public String getSizeMacro () {
return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());
}
private int getSize () {
return (al.size() == 0)? 1 : al.size();
}
public String getExistanceMacro () {
return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
}
public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
final String name = "GuidTable";
CStructTypeDeclaration decl;
String cCode = "";
cCode += String.format(PcdDatabase.GuidTableDeclaration, phase);
decl = new CStructTypeDeclaration (
name,
4,
cCode,
true
);
declaList.add(decl);
cCode = PcdDatabase.genInstantiationStr(getInstantiation());
instTable.put(name, cCode);
}
private String getUuidCString (UUID uuid) {
String[] guidStrArray;
guidStrArray =(uuid.toString()).split("-");
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}}",
guidStrArray[0],
guidStrArray[1],
guidStrArray[2],
(guidStrArray[3].substring(0, 2)),
(guidStrArray[3].substring(2, 4)),
(guidStrArray[4].substring(0, 2)),
(guidStrArray[4].substring(2, 4)),
(guidStrArray[4].substring(4, 6)),
(guidStrArray[4].substring(6, 8)),
(guidStrArray[4].substring(8, 10)),
(guidStrArray[4].substring(10, 12))
);
}
private ArrayList<String> getInstantiation () {
ArrayList<String> Output = new ArrayList<String>();
Output.add("/* GuidTable */");
Output.add("{");
if (al.size() == 0) {
Output.add("\t" + getUuidCString(new UUID(0, 0)));
}
for (int i = 0; i < al.size(); i++) {
String str = "\t" + getUuidCString(al.get(i));
str += "/* " + alComments.get(i) + " */";
if (i != (al.size() - 1)) {
str += ",";
}
Output.add(str);
bodyLineNum++;
}
Output.add("}");
return Output;
}
public int add (UUID uuid, String name) {
//
// Check if GuidTable has this entry already.
// If so, return the GuidTable index.
//
for (int i = 0; i < al.size(); i++) {
if (al.get(i).compareTo(uuid) == 0) {
return i;
}
}
len++;
al.add(uuid);
alComments.add(name);
//
// Return the previous Table Index
//
return len - 1;
}
}
/**
SkuIdTable
This class is used to store the SKU IDs in a PCD database.
**/
class SkuIdTable {
private ArrayList<Integer[]> al;
private ArrayList<String> alComment;
private String phase;
private int len;
public SkuIdTable (String phase) {
this.phase = phase;
al = new ArrayList<Integer[]>();
alComment = new ArrayList<String>();
len = 0;
}
public String getSizeMacro () {
return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());
}
private int getSize () {
return (len == 0)? 1 : len;
}
public String getExistanceMacro () {
return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
}
public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
final String name = "SkuIdTable";
CStructTypeDeclaration decl;
String cCode = "";
cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase);
decl = new CStructTypeDeclaration (
name,
1,
cCode,
true
);
declaList.add(decl);
cCode = PcdDatabase.genInstantiationStr(getInstantiation());
instTable.put(name, cCode);
//
// SystemSkuId is in PEI phase PCD Database
//
if (phase.equalsIgnoreCase("PEI")) {
decl = new CStructTypeDeclaration (
"SystemSkuId",
1,
String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),
true
);
declaList.add(decl);
instTable.put("SystemSkuId", "0");
}
}
private ArrayList<String> getInstantiation () {
ArrayList<String> Output = new ArrayList<String> ();
Output.add("/* SkuIdTable */");
Output.add("{");
if (al.size() == 0) {
Output.add("\t0");
}
for (int index = 0; index < al.size(); index++) {
String str;
str = "/* " + alComment.get(index) + "*/ ";
str += "/* MaxSku */ ";
Integer[] ia = al.get(index);
str += "\t" + ia[0].toString() + ", ";
for (int index2 = 1; index2 < ia.length; index2++) {
str += ia[index2].toString();
if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {
str += ", ";
}
}
Output.add(str);
}
Output.add("}");
return Output;
}
public int add (Token token) {
int index;
int pos;
//
// Check if this SKU_ID Array is already in the table
//
pos = 0;
for (Object o: al) {
Integer [] s = (Integer[]) o;
boolean different = false;
if (s[0] == token.getSkuIdCount()) {
for (index = 1; index < s.length; index++) {
if (s[index] != token.skuData.get(index-1).id) {
different = true;
break;
}
}
} else {
different = true;
}
if (different) {
pos += s[0] + 1;
} else {
return pos;
}
}
Integer [] skuIds = new Integer[token.skuData.size() + 1];
skuIds[0] = new Integer(token.skuData.size());
for (index = 1; index < skuIds.length; index++) {
skuIds[index] = new Integer(token.skuData.get(index - 1).id);
}
index = len;
len += skuIds.length;
al.add(skuIds);
alComment.add(token.getPrimaryKeyString());
return index;
}
}
class LocalTokenNumberTable {
private ArrayList<String> al;
private ArrayList<String> alComment;
private String phase;
private int len;
public LocalTokenNumberTable (String phase) {
this.phase = phase;
al = new ArrayList<String>();
alComment = new ArrayList<String>();
len = 0;
}
public String getSizeMacro () {
return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())
+ String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());
}
public int getSize () {
return (al.size() == 0)? 1 : al.size();
}
public String getExistanceMacro () {
return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
}
public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
final String name = "LocalTokenNumberTable";
CStructTypeDeclaration decl;
String cCode = "";
cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
decl = new CStructTypeDeclaration (
name,
4,
cCode,
true
);
declaList.add(decl);
cCode = PcdDatabase.genInstantiationStr(getInstantiation());
instTable.put(name, cCode);
}
private ArrayList<String> getInstantiation () {
ArrayList<String> output = new ArrayList<String>();
output.add("/* LocalTokenNumberTable */");
output.add("{");
if (al.size() == 0) {
output.add("\t0");
}
for (int index = 0; index < al.size(); index++) {
String str;
str = "\t" + (String)al.get(index);
str += " /* " + alComment.get(index) + " */ ";
if (index != (al.size() - 1)) {
str += ",";
}
output.add(str);
}
output.add("}");
return output;
}
public int add (Token token) {
int index = len;
String str;
len++;
str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());
if (token.isUnicodeStringType()) {
str += " | PCD_TYPE_STRING";
}
if (token.isSkuEnable()) {
str += " | PCD_TYPE_SKU_ENABLED";
}
if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
str += " | PCD_TYPE_HII";
}
if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
str += " | PCD_TYPE_VPD";
}
switch (token.datumType) {
case UINT8:
case BOOLEAN:
str += " | PCD_DATUM_TYPE_UINT8";
break;
case UINT16:
str += " | PCD_DATUM_TYPE_UINT16";
break;
case UINT32:
str += " | PCD_DATUM_TYPE_UINT32";
break;
case UINT64:
str += " | PCD_DATUM_TYPE_UINT64";
break;
case POINTER:
str += " | PCD_DATUM_TYPE_POINTER";
break;
}
al.add(str);
alComment.add(token.getPrimaryKeyString());
return index;
}
}
/**
ExMapTable
This class is used to store the table of mapping information
between DynamicEX ID pair(Guid, TokenNumber) and
the local token number assigned by PcdDatabase class.
**/
class ExMapTable {
/**
ExTriplet
This class is used to store the mapping information
between DynamicEX ID pair(Guid, TokenNumber) and
the local token number assigned by PcdDatabase class.
**/
class ExTriplet {
public Integer guidTableIdx;
public Long exTokenNumber;
public Long localTokenIdx;
public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {
this.guidTableIdx = new Integer(guidTableIdx);
this.exTokenNumber = new Long(exTokenNumber);
this.localTokenIdx = new Long(localTokenIdx);
}
}
private ArrayList<ExTriplet> al;
private Map<ExTriplet, String> alComment;
private String phase;
private int len;
private int bodyLineNum;
public ExMapTable (String phase) {
this.phase = phase;
al = new ArrayList<ExTriplet>();
alComment = new HashMap<ExTriplet, String>();
bodyLineNum = 0;
len = 0;
}
public String getSizeMacro () {
return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())
+ String.format(PcdDatabase.ExTokenNumber, phase, al.size());
}
public String getExistanceMacro () {
return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
}
public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
final String exMapTableName = "ExMapTable";
sortTable();
CStructTypeDeclaration decl;
String cCode = "";
cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase);
decl = new CStructTypeDeclaration (
exMapTableName,
4,
cCode,
true
);
declaList.add(decl);
cCode = PcdDatabase.genInstantiationStr(getInstantiation());
instTable.put(exMapTableName, cCode);
}
private ArrayList<String> getInstantiation () {
ArrayList<String> Output = new ArrayList<String>();
Output.add("/* ExMapTable */");
Output.add("{");
if (al.size() == 0) {
Output.add("\t{0, 0, 0}");
}
int index;
for (index = 0; index < al.size(); index++) {
String str;
ExTriplet e = (ExTriplet)al.get(index);
str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";
str += e.localTokenIdx.toString() + ", ";
str += e.guidTableIdx.toString();
str += "}" + " /* " + alComment.get(e) + " */" ;
if (index != al.size() - 1) {
str += ",";
}
Output.add(str);
bodyLineNum++;
}
Output.add("}");
return Output;
}
public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {
int index = len;
len++;
ExTriplet et = new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx);
al.add(et);
alComment.put(et, name);
return index;
}
private int getTableLen () {
return al.size() == 0 ? 1 : al.size();
}
//
// To simplify the algorithm for GetNextToken and GetNextTokenSpace in
// PCD PEIM/Driver, we need to sort the ExMapTable according to the
// following order:
// 1) ExGuid
// 2) ExTokenNumber
//
class ExTripletComp implements Comparator<ExTriplet> {
public int compare (ExTriplet a, ExTriplet b) {
if (a.guidTableIdx == b.guidTableIdx ) {
//
// exTokenNumber is long, we can't use simple substraction.
//
if (a.exTokenNumber > b.exTokenNumber) {
return 1;
} else if (a.exTokenNumber == b.exTokenNumber) {
return 0;
} else {
return -1;
}
}
return a.guidTableIdx - b.guidTableIdx;
}
}
private void sortTable () {
java.util.Comparator<ExTriplet> comparator = new ExTripletComp();
java.util.Collections.sort(al, comparator);
}
}
/**
PcdDatabase
This class is used to generate C code for Autogen.h and Autogen.c of
a PCD service DXE driver and PCD service PEIM.
**/
public class PcdDatabase {
private final static int SkuHeadAlignmentSize = 4;
private final String newLine = "\r\n";
private final String commaNewLine = ",\r\n";
private final String tab = "\t";
public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
public final static String SizeTableDeclaration = "SIZE_INFO SizeTable[%s_SIZE_TABLE_SIZE];\r\n";
public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";
public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";
public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";
public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
public final static String SizeTableSizeMacro = "#define %s_SIZE_TABLE_SIZE %d\r\n";
public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";
public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";
public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";
public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";
public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";
public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";
public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";
public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";
private final static String skuDataTableTemplate = "SkuDataTable";
private StringTable stringTable;
private GuidTable guidTable;
private LocalTokenNumberTable localTokenNumberTable;
private SkuIdTable skuIdTable;
private SizeTable sizeTable;
private ExMapTable exMapTable;
private ArrayList<Token> alTokens;
private String phase;
private int assignedTokenNumber;
//
// Use two class global variable to store
// temperary
//
private String privateGlobalName;
private String privateGlobalCCode;
//
// After Major changes done to the PCD
// database generation class PcdDatabase
// Please increment the version and please
// also update the version number in PCD
// service PEIM and DXE driver accordingly.
//
private final int version = 2;
private String hString;
private String cString;
/**
Constructor for PcdDatabase class.
<p>We have two PCD dynamic(ex) database for the Framework implementation. One
for PEI phase and the other for DXE phase. </p>
@param alTokens A ArrayList of Dynamic(EX) PCD entry.
@param exePhase The phase to generate PCD database for: valid input
is "PEI" or "DXE".
@param startLen The starting Local Token Number for the PCD database. For
PEI phase, the starting Local Token Number starts from 0.
For DXE phase, the starting Local Token Number starts
from the total number of PCD entry of PEI phase.
@return void
**/
public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {
phase = exePhase;
stringTable = new StringTable(phase);
guidTable = new GuidTable(phase);
localTokenNumberTable = new LocalTokenNumberTable(phase);
skuIdTable = new SkuIdTable(phase);
sizeTable = new SizeTable(phase);
exMapTable = new ExMapTable(phase);
//
// Local token number 0 is reserved for INVALID_TOKEN_NUMBER.
// So we will increment 1 for the startLen passed from the
// constructor.
//
assignedTokenNumber = startLen + 1;
this.alTokens = alTokens;
}
private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {
for (int i = 0; i < alTokens.size(); i++) {
Token t = (Token)alTokens.get(i);
if (t.isDynamicEx()) {
exTokens.add(t);
} else {
nexTokens.add(t);
}
}
return;
}
private int getDataTypeAlignmentSize (Token token) {
switch (token.datumType) {
case UINT8:
return 1;
case UINT16:
return 2;
case UINT32:
return 4;
case UINT64:
return 8;
case POINTER:
return 1;
case BOOLEAN:
return 1;
default:
return 1;
}
}
private int getHiiPtrTypeAlignmentSize(Token token) {
switch (token.datumType) {
case UINT8:
return 1;
case UINT16:
return 2;
case UINT32:
return 4;
case UINT64:
return 8;
case POINTER:
if (token.isHiiEnable()) {
if (token.isHiiDefaultValueUnicodeStringType()) {
return 2;
}
}
return 1;
case BOOLEAN:
return 1;
default:
return 1;
}
}
private int getAlignmentSize (Token token) {
if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
return 2;
}
if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
return 4;
}
if (token.isUnicodeStringType()) {
return 2;
}
return getDataTypeAlignmentSize(token);
}
public String getCString () {
return cString;
}
public String getHString () {
return hString;
}
private void genCodeWorker(Token t,
ArrayList<CStructTypeDeclaration> declaList,
HashMap<String, String> instTable, String phase)
throws EntityException {
CStructTypeDeclaration decl;
//
// Insert SKU_HEAD if isSkuEnable is true
//
if (t.isSkuEnable()) {
int tableIdx;
tableIdx = skuIdTable.add(t);
decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),
SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);
declaList.add(decl);
instTable.put(t.getPrimaryKeyString(),
getSkuEnabledTypeInstantiaion(t, tableIdx));
}
//
// Insert PCD_ENTRY declaration and instantiation
//
getCDeclarationString(t);
decl = new CStructTypeDeclaration(privateGlobalName,
getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());
declaList.add(decl);
if (t.hasDefaultValue()) {
instTable.put(privateGlobalName,
getTypeInstantiation(t, declaList, instTable, phase)
);
}
}
private void ProcessTokens (List<Token> tokens,
ArrayList<CStructTypeDeclaration> cStructDeclList,
HashMap<String, String> cStructInstTable,
String phase
)
throws EntityException {
for (int idx = 0; idx < tokens.size(); idx++) {
Token t = tokens.get(idx);
genCodeWorker (t, cStructDeclList, cStructInstTable, phase);
sizeTable.add(t);
localTokenNumberTable.add(t);
t.tokenNumber = assignedTokenNumber++;
//
// Add a mapping if this dynamic PCD entry is a EX type
//
if (t.isDynamicEx()) {
exMapTable.add((int)t.tokenNumber,
t.dynamicExTokenNumber,
guidTable.add(translateSchemaStringToUUID(t.tokenSpaceName), t.getPrimaryKeyString()),
t.getPrimaryKeyString()
);
}
}
}
public void genCode () throws EntityException {
ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();
HashMap<String, String> cStructInstTable = new HashMap<String, String>();
List<Token> nexTokens = new ArrayList<Token> ();
List<Token> exTokens = new ArrayList<Token> ();
getNonExAndExTokens (alTokens, nexTokens, exTokens);
//
// We have to process Non-Ex type PCD entry first. The reason is
// that our optimization assumes that the Token Number of Non-Ex
// PCD entry start from 1 (for PEI phase) and grows continously upwards.
//
// EX type token number starts from the last Non-EX PCD entry and
// grows continously upwards.
//
ProcessTokens (nexTokens, cStructDeclList, cStructInstTable, phase);
ProcessTokens (exTokens, cStructDeclList, cStructInstTable, phase);
stringTable.genCode(cStructDeclList, cStructInstTable);
skuIdTable.genCode(cStructDeclList, cStructInstTable, phase);
exMapTable.genCode(cStructDeclList, cStructInstTable, phase);
localTokenNumberTable.genCode(cStructDeclList, cStructInstTable, phase);
sizeTable.genCode(cStructDeclList, cStructInstTable, phase);
guidTable.genCode(cStructDeclList, cStructInstTable, phase);
hString = genCMacroCode ();
HashMap <String, String> result;
result = genCStructCode(cStructDeclList,
cStructInstTable,
phase
);
hString += result.get("initDeclStr");
hString += result.get("uninitDeclStr");
hString += String.format("#define PCD_%s_SERVICE_DRIVER_AUTOGEN_VERSION %d", phase, version);
cString = newLine + newLine + result.get("initInstStr");
}
private String genCMacroCode () {
String macroStr = "";
//
// Generate size info Macro for all Tables
//
macroStr += guidTable.getSizeMacro();
macroStr += stringTable.getSizeMacro();
macroStr += skuIdTable.getSizeMacro();
macroStr += localTokenNumberTable.getSizeMacro();
macroStr += exMapTable.getSizeMacro();
macroStr += sizeTable.getSizeMacro();
//
// Generate existance info Macro for all Tables
//
macroStr += guidTable.getExistanceMacro();
macroStr += stringTable.getExistanceMacro();
macroStr += skuIdTable.getExistanceMacro();
macroStr += localTokenNumberTable.getExistanceMacro();
macroStr += exMapTable.getExistanceMacro();
macroStr += newLine;
return macroStr;
}
private HashMap <String, String> genCStructCode(
ArrayList<CStructTypeDeclaration> declaList,
HashMap<String, String> instTable,
String phase
) {
int i;
HashMap <String, String> result = new HashMap<String, String>();
HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();
HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();
HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();
//
// Initialize the storage for each alignment
//
for (i = 8; i > 0; i>>=1) {
alignmentInitDecl.put(new Integer(i), new ArrayList<String>());
alignmentInitInst.put(new Integer(i), new ArrayList<String>());
alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());
}
String initDeclStr = "typedef struct {" + newLine;
String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;
String uninitDeclStr = "typedef struct {" + newLine;
//
// Sort all C declaration and instantiation base on Alignment Size
//
for (Object d : declaList) {
CStructTypeDeclaration decl = (CStructTypeDeclaration) d;
if (decl.initTable) {
alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));
} else {
alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
}
}
//
// Generate code for every alignment size
//
boolean uinitDatabaseEmpty = true;
for (int align = 8; align > 0; align >>= 1) {
ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));
ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));
for (i = 0; i < declaListBasedOnAlignment.size(); i++) {
initDeclStr += tab + declaListBasedOnAlignment.get(i);
initInstStr += tab + instListBasedOnAlignment.get(i);
//
// We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE
// has a least one data memember with alignment size of 1. So we can
// remove the last "," in the C structure instantiation string. Luckily,
// this is true as both data structure has SKUID_TABLE anyway.
//
if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {
initInstStr += newLine;
} else {
initInstStr += commaNewLine;
}
}
declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));
if (declaListBasedOnAlignment.size() != 0) {
uinitDatabaseEmpty = false;
}
for (Object d : declaListBasedOnAlignment) {
String s = (String)d;
uninitDeclStr += tab + s;
}
}
if (uinitDatabaseEmpty) {
uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");
}
initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;
initInstStr += "};" + newLine;
uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;
result.put("initDeclStr", initDeclStr);
result.put("initInstStr", initInstStr);
result.put("uninitDeclStr", uninitDeclStr);
return result;
}
public static String genInstantiationStr (ArrayList<String> alStr) {
String str = "";
for (int i = 0; i< alStr.size(); i++) {
if (i != 0) {
str += "\t";
}
str += alStr.get(i);
if (i != alStr.size() - 1) {
str += "\r\n";
}
}
return str;
}
private String getSkuEnabledTypeDeclaration (Token token) {
return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());
}
private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());
}
private String getDataTypeInstantiationForVariableDefault (Token token, String cName, int skuId) {
return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);
}
private String getCType (Token t)
throws EntityException {
if (t.isHiiEnable()) {
return "VARIABLE_HEAD";
}
if (t.isVpdEnable()) {
return "VPD_HEAD";
}
if (t.isUnicodeStringType()) {
return "STRING_HEAD";
}
switch (t.datumType) {
case UINT64:
return "UINT64";
case UINT32:
return "UINT32";
case UINT16:
return "UINT16";
case UINT8:
return "UINT8";
case BOOLEAN:
return "BOOLEAN";
case POINTER:
return "UINT8";
default:
throw new EntityException("Unknown DatumType in getDataTypeCDeclaration");
}
}
//
// privateGlobalName and privateGlobalCCode is used to pass output to caller of getCDeclarationString
//
private void getCDeclarationString(Token t)
throws EntityException {
if (t.isSkuEnable()) {
privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);
} else {
privateGlobalName = t.getPrimaryKeyString();
}
String type = getCType(t);
if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable()) && (!t.isUnicodeStringType())) {
int bufferSize;
if (t.isASCIIStringType()) {
//
// Build tool will add a NULL string at the end of the ASCII string
//
bufferSize = t.datumSize + 1;
} else {
bufferSize = t.datumSize;
}
privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);
} else {
privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());
}
}
private String getDataTypeDeclarationForVariableDefault (Token token, String cName, int skuId)
throws EntityException {
String typeStr;
if (token.datumType == Token.DATUM_TYPE.UINT8) {
typeStr = "UINT8";
} else if (token.datumType == Token.DATUM_TYPE.UINT16) {
typeStr = "UINT16";
} else if (token.datumType == Token.DATUM_TYPE.UINT32) {
typeStr = "UINT32";
} else if (token.datumType == Token.DATUM_TYPE.UINT64) {
typeStr = "UINT64";
} else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
typeStr = "BOOLEAN";
} else if (token.datumType == Token.DATUM_TYPE.POINTER) {
int size;
if (token.isHiiDefaultValueUnicodeStringType()) {
typeStr = "UINT16";
//
// Include the NULL charactor
//
size = token.datumSize / 2 + 1;
} else {
typeStr = "UINT8";
if (token.isHiiDefaultValueASCIIStringType()) {
//
// Include the NULL charactor
//
size = token.datumSize + 1;
} else {
size = token.datumSize;
}
}
return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);
} else {
throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");
}
return String.format("%-20s%s;\r\n", typeStr, cName);
}
private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {
int i;
String s;
s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;
s += tab + "{" + newLine;
for (i = 0; i < t.skuData.size(); i++) {
if (t.isUnicodeStringType()) {
s += tab + tab + String.format(" %d ", stringTable.add(t.skuData.get(i).value.value, t));
} else if (t.isHiiEnable()) {
/* VPD_HEAD definition
typedef struct {
UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.
UINT16 StringIndex; // Offset in String Table in units of UINT16.
UINT16 Offset; // Offset in Variable
UINT16 DefaultValueOffset; // Offset of the Default Value
} VARIABLE_HEAD ;
*/
String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i);
s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),
stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),
t.skuData.get(i).value.variableOffset,
String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)
);
//
// We need to support the default value, so we add the declaration and
// the instantiation for the default value.
//
CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,
getHiiPtrTypeAlignmentSize(t),
getDataTypeDeclarationForVariableDefault(t, variableDefaultName, i),
true
);
declaList.add(decl);
instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault (t, variableDefaultName, i));
} else if (t.isVpdEnable()) {
/* typedef struct {
UINT32 Offset;
} VPD_HEAD;
*/
s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);
} else {
if (t.isByteStreamType()) {
//
// Byte stream type input has their own "{" "}", so we won't help to insert.
//
s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);
} else {
s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);
}
}
if (i != t.skuData.size() - 1) {
s += commaNewLine;
} else {
s += newLine;
}
}
s += tab + "}";
return s;
}
public static String getPcdDatabaseCommonDefinitions () {
String retStr;
retStr = "//\r\n";
retStr += "// The following definition will be generated by build tool\r\n";
retStr += "//\r\n";
retStr += "\r\n";
retStr += "//\r\n";
retStr += "// Common definitions\r\n";
retStr += "//\r\n";
retStr += "typedef UINT8 SKU_ID;\r\n";
retStr += "\r\n";
retStr += "#define PCD_TYPE_SHIFT 28\r\n";
retStr += "\r\n";
retStr += "#define PCD_TYPE_DATA (0x0 << PCD_TYPE_SHIFT)\r\n";
retStr += "#define PCD_TYPE_HII (0x8 << PCD_TYPE_SHIFT)\r\n";
retStr += "#define PCD_TYPE_VPD (0x4 << PCD_TYPE_SHIFT)\r\n";
retStr += "#define PCD_TYPE_SKU_ENABLED (0x2 << PCD_TYPE_SHIFT)\r\n";
retStr += "#define PCD_TYPE_STRING (0x1 << PCD_TYPE_SHIFT)\r\n";
retStr += "\r\n";
retStr += "#define PCD_TYPE_ALL_SET (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)\r\n";
retStr += "\r\n";
retStr += "#define PCD_DATUM_TYPE_SHIFT 24\r\n";
retStr += "\r\n";
retStr += "#define PCD_DATUM_TYPE_POINTER (0x0 << PCD_DATUM_TYPE_SHIFT)\r\n";
retStr += "#define PCD_DATUM_TYPE_UINT8 (0x1 << PCD_DATUM_TYPE_SHIFT)\r\n";
retStr += "#define PCD_DATUM_TYPE_UINT16 (0x2 << PCD_DATUM_TYPE_SHIFT)\r\n";
retStr += "#define PCD_DATUM_TYPE_UINT32 (0x4 << PCD_DATUM_TYPE_SHIFT)\r\n";
retStr += "#define PCD_DATUM_TYPE_UINT64 (0x8 << PCD_DATUM_TYPE_SHIFT)\r\n";
retStr += "\r\n";
retStr += "#define PCD_DATUM_TYPE_ALL_SET (PCD_DATUM_TYPE_POINTER | \\\r\n";
retStr += " PCD_DATUM_TYPE_UINT8 | \\\r\n";
retStr += " PCD_DATUM_TYPE_UINT16 | \\\r\n";
retStr += " PCD_DATUM_TYPE_UINT32 | \\\r\n";
retStr += " PCD_DATUM_TYPE_UINT64)\r\n";
retStr += "\r\n";
retStr += "\r\n";
retStr += "#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET))\r\n";
retStr += "\r\n";
retStr += "typedef struct {\r\n";
retStr += " UINT32 ExTokenNumber;\r\n";
retStr += " UINT16 LocalTokenNumber; // PCD Number of this particular platform build\r\n";
retStr += " UINT16 ExGuidIndex; // Index of GuidTable\r\n";
retStr += "} DYNAMICEX_MAPPING;\r\n";
retStr += "\r\n";
retStr += "\r\n";
retStr += "typedef struct {\r\n";
retStr += " UINT32 SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler\r\n";
retStr += " UINT32 SkuIdTableOffset; //Offset from the PCD_DB\r\n";
retStr += "} SKU_HEAD;\r\n";
retStr += "\r\n";
retStr += "\r\n";
retStr += "typedef struct {\r\n";
retStr += " UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r\n";
retStr += " UINT16 StringIndex; // Offset in String Table in units of UINT16.\r\n";
retStr += " UINT16 Offset; // Offset in Variable\r\n";
retStr += " UINT16 DefaultValueOffset; // Offset of the Default Value\r\n";
retStr += "} VARIABLE_HEAD ;\r\n";
retStr += "\r\n";
retStr += "\r\n";
retStr += "typedef struct {\r\n";
retStr += " UINT32 Offset;\r\n";
retStr += "} VPD_HEAD;\r\n";
retStr += "\r\n";
retStr += "typedef UINT16 STRING_HEAD;\r\n";
retStr += "\r\n";
retStr += "typedef UINT16 SIZE_INFO;\r\n";
retStr += "\r\n";
retStr += "#define offsetof(s,m) (UINT32) (UINTN) &(((s *)0)->m)\r\n";
retStr += "\r\n";
retStr += "\r\n";
retStr += "\r\n";
return retStr;
}
public static String getPcdDxeDatabaseDefinitions ()
throws EntityException {
String retStr = "";
retStr += "\r\n";
retStr += "typedef struct {\r\n";
retStr += " DXE_PCD_DATABASE_INIT Init;\r\n";
retStr += " DXE_PCD_DATABASE_UNINIT Uninit;\r\n";
retStr += "} DXE_PCD_DATABASE;\r\n";
retStr += "\r\n";
retStr += "\r\n";
retStr += "typedef struct {\r\n";
retStr += " PEI_PCD_DATABASE PeiDb;\r\n";
retStr += " DXE_PCD_DATABASE DxeDb;\r\n";
retStr += "} PCD_DATABASE;\r\n";
retStr += "\r\n";
retStr += "#define DXE_NEX_TOKEN_NUMBER (DXE_LOCAL_TOKEN_NUMBER - DXE_EX_TOKEN_NUMBER)\r\n";
retStr += "\r\n";
retStr += "#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)\r\n";
retStr += "\r\n";
retStr += "\r\n";
return retStr;
}
public static String getPcdPeiDatabaseDefinitions ()
throws EntityException {
String retStr = "";
retStr += "\r\n";
retStr += "typedef struct {\r\n";
retStr += " PEI_PCD_DATABASE_INIT Init;\r\n";
retStr += " PEI_PCD_DATABASE_UNINIT Uninit;\r\n";
retStr += "} PEI_PCD_DATABASE;\r\n";
retStr += "\r\n";
retStr += "#define PEI_NEX_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER - PEI_EX_TOKEN_NUMBER)\r\n";
retStr += "\r\n";
return retStr;
}
/**
Translate the schema string to UUID instance.
In schema, the string of UUID is defined as following two types string:
1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
)*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
2) GuidNamingConvention: pattern =
[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}
This function will convert string and create uuid instance.
@param uuidString UUID string in XML file
@return UUID UUID instance
**/
private UUID translateSchemaStringToUUID(String uuidString)
throws EntityException {
String temp;
String[] splitStringArray;
int index;
int chIndex;
int chLen;
if (uuidString == null) {
return null;
}
if (uuidString.length() == 0) {
return null;
}
if (uuidString.equals("0") ||
uuidString.equalsIgnoreCase("0x0")) {
return new UUID(0, 0);
}
uuidString = uuidString.replaceAll("\\{", "");
uuidString = uuidString.replaceAll("\\}", "");
//
// If the UUID schema string is GuidArrayType type then need translate
// to GuidNamingConvention type at first.
//
if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
splitStringArray = uuidString.split("," );
if (splitStringArray.length != 11) {
throw new EntityException ("[FPD file error] Wrong format for GUID string: " + uuidString);
}
//
// Remove blank space from these string and remove header string "0x"
//
for (index = 0; index < 11; index ++) {
splitStringArray[index] = splitStringArray[index].trim();
splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
}
//
// Add heading '0' to normalize the string length
//
for (index = 3; index < 11; index ++) {
chLen = splitStringArray[index].length();
for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
splitStringArray[index] = "0" + splitStringArray[index];
}
}
//
// construct the final GuidNamingConvention string
//
temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
splitStringArray[0],
splitStringArray[1],
splitStringArray[2],
splitStringArray[3],
splitStringArray[4],
splitStringArray[5],
splitStringArray[6],
splitStringArray[7],
splitStringArray[8],
splitStringArray[9],
splitStringArray[10]);
uuidString = temp;
}
return UUID.fromString(uuidString);
}
}