void GenUnionFactory() { WriteComment("Holds static factory method for instantiating TPM unions.\n" + "Note: A wrapper class is used instead of simply static function solely " + "for the sake of uniformity with languages like C# and Java."); Write("class UnionFactory"); TabIn("{"); WriteComment("Creates specific TPM union member based on the union type and selector (tag) value"); Write("@SuppressWarnings(\"unchecked\")"); Write("public static <U extends TpmUnion, S extends TpmEnum<S>>"); Write("U create(String unionType, S selector) // S = TPM_ALG_ID | TPM_CAP | TPM_ST"); TabIn("{"); string elsePref = ""; foreach (TpmUnion u in TpmTypes.Get <TpmUnion>()) { TabIn($"{elsePref}if (unionType == \"{u.Name}\")"); elsePref = "else "; TabIn($"switch ((({GetUnionSelectorType(u)})selector).asEnum()) {{"); foreach (UnionMember m in u.Members) { string newObj = m.Type.IsElementary() ? TargetLang.Null : $"new {m.Type.Name}()"; Write($"case {m.SelectorValue.Name}: return (U) {newObj};"); } Write("default:"); TabOut("}", false); // switch (selector) TabOut(); // if / else if } TabIn("else"); Write("throw new RuntimeException(\"UnionFactory::Create(): Unknown union type \" + unionType);"); TabOut("throw new RuntimeException(\"Unknown selector value \" + selector.toString() + \" for union \" + unionType);"); TabOut("} // create()"); TabOut("}; // class UnionFactory"); }
} // GenStruct() void GenerateTpmCommandPrototypes() { // Command prototypes var commands = TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest()); TabIn(); foreach (TpmStruct s in commands) { GenCommand(s, CommandFlavor.Synch); } Write("class _DLLEXP_ AsyncMethods"); Write("{"); Write("protected: Tpm2& theTpm;"); Write("public: AsyncMethods(Tpm2& _tpm) : theTpm(_tpm) {}"); TabIn("public:"); foreach (TpmStruct s in commands) { GenCommand(s, CommandFlavor.AsyncCommand); } foreach (TpmStruct s in commands) { GenCommand(s, CommandFlavor.AsyncResponse); } TabOut("};"); TabOut("public:"); TabIn(); Write("AsyncMethods Async;"); TabOut("};"); Write("_TPMCPP_END"); } // GenCommands()
void GenerateTpmTypesHdr() { foreach (var e in TpmTypes.Get <TpmEnum>()) { GenEnum(e); } foreach (var bf in TpmTypes.Get <TpmBitfield>()) { GenBitfield(bf); } WriteComment(AsSummary("Base class for TPM union interfaces")); Write("class _DLLEXP_ TpmUnion: public virtual TpmStructure {};"); foreach (var u in TpmTypes.Get <TpmUnion>()) { GenUnion(u); } foreach (var s in TpmTypes.Get <TpmStruct>()) { GenStructDecl(s); } Write("_TPMCPP_END"); } // GenerateHeader()
static void FixTpm2bStructs() { foreach (var s in TpmTypes.Get <TpmStruct>().Where(s => s.Fields.Count == 2 && s.StripTypedefs().SpecName.StartsWith("TPM2B_"))) { var tagField = s.Fields[0]; var dataField = s.Fields[1]; if (tagField.MarshalType == MarshalType.ArrayCount) { // A TPM2B struct has a byte count as the first member that contains the size of the second member. // The second member can be either a byte buffer or a data structure. In the latter case the type // of the data structure can be obtained from the name of the TPM2B struct. string structName = s.SpecName.Replace("TPM2B_", "TPMS_"); if (!TpmTypes.Contains(structName)) { continue; } dataField = s.Fields[1] = new StructField(structName, dataField.Name, dataField.Comment); } tagField.MarshalType = MarshalType.LengthOfStruct; dataField.MarshalType = MarshalType.SizedStruct; tagField.SizedField = dataField; dataField.SizeTagField = tagField; dataField.Domain = tagField.Domain; } }
internal override void Generate() { WriteAutoGeneratedSourceHeader(); Write("from .TpmStructure import *"); Write("from .TpmEnum import *"); Write(""); // First generate enums foreach (var e in TpmTypes.Get <TpmEnum>()) { GenEnum(e); } foreach (var b in TpmTypes.Get <TpmBitfield>()) { GenBitfield(b); } Write("from .Crypt import *" + "\r\n"); // Then generate unions and structures GenUnions(); foreach (var s in TpmTypes.Get <TpmStruct>()) { GenStruct(s); } File.WriteAllText(RootDir + "TpmTypes.py", GeneratedCode.ToString()); GeneratedCode.Clear(); // Now generate the TPM methods GenCommands(); File.WriteAllText(RootDir + "Tpm.py", GeneratedCode.ToString()); GeneratedCode.Clear(); }
} // GenStruct() void GenCommands() { string tpmComment = "The Tpm class provides Java functions to program a TPM.\n" + "<P>\n" + "The TPM spec defines TPM command with names like TPM2_PCR_Read().\n" + "The Java rendering of the spec drops the 'TPM2_' prefix: e.g. PCR_Read().\n" + "The Tpm and TpmBase classes also provide a few helper-functions: for example,\n" + "the command _allowErrors() tells to not throw an exception if the next\n" + "TPM command returns an error. Such helpers have names beginning with underscore '_'.\n" + "<P>\n" + "Tpm objects must be \"connected\" to a physical TPM or TPM simulator using the _setDevice()\n" + "method. Some devices (like the TPM simulator) need to be configured before they can be used.\n" + "See the sample code that is part of the TSS.Java distribution for more information."; WriteComment(tpmComment); Write($"public class Tpm extends TpmBase"); TabIn("{"); foreach (var req in TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest())) { GenCommand(req); } InsertSnip("Tpm"); TabOut("}", false); } // GenCommands()
internal override void Generate() { WriteAutoGeneratedSourceHeader(); Write("import { TpmMarshaller, TpmBuffer } from \"./TpmMarshaller.js\";\r\n" + "import { TpmStructure, ReqStructure, RespStructure, SessEncInfo } from \"./TpmStructure.js\";\r\n" + "\r\n" + "import { Crypto } from \"./Crypt.js\";\r\n" + "\r\n"); // First generate enums foreach (var e in TpmTypes.Get <TpmEnum>()) { GenEnum(e); } foreach (var b in TpmTypes.Get <TpmBitfield>()) { GenBitfield(b); } // Then generate unions and structures GenUnions(); foreach (var s in TpmTypes.Get <TpmStruct>()) { GenStruct(s); } File.WriteAllText(RootDir + "TpmTypes.ts", GeneratedCode.ToString()); GeneratedCode.Clear(); // Now generate the TPM methods GenCommands(); File.WriteAllText(RootDir + "Tpm.ts", GeneratedCode.ToString()); GeneratedCode.Clear(); }
public bool Remove(TpmNamedConstant member) { if (!TpmTypes.RemoveConstant(member.SpecName)) { return(false); } return(Members.Remove(member)); }
public TpmStruct(string typeName, string comment, TpmStruct derivedFrom = null, StructInfo info = null, bool customizedImpl = false) : base(typeName, comment) { Fields = new List <StructField>(); DerivedFrom = derivedFrom; Debug.Assert(DerivedFrom == null || TpmTypes.Contains(DerivedFrom.SpecName)); Info = info ?? new TpmStructInfo(); }
public TpmNamedConstant Add(string name, string value, string comment) { var nc = new TpmNamedConstant(this, name, value, comment); if (!TpmTypes.AddConstant(nc)) { return(null); } Members.Add(nc); return(nc); }
/// <summary> This method is called before code generation for the given target /// language begins </summary> public static void SetTargetLang(Lang lang) { // This assertion will fail if a new target language is added to the Lang enum // without also adding the corresponding Debug.Assert(Enum.GetValues(typeof(Lang)).Length == CodeGenerators.Length + 2); _curLang = lang; _thisQual = DotNet || Cpp || Java ? "" : This + "."; _null = Py ? "None" : Cpp ? "nullptr" : "null"; _new = DotNet || Java || Node ? "new " : ""; _quote = Py || Node ? "'" : "\""; _digestSize = Cpp ? "TPMT_HA::DigestSize" : "Crypto.digestSize"; GeneratedEnums = new HashSet <TpmEnum>(); // First translate names foreach (var t in TpmTypes.TheTypes) { t.Name = TranslateTypeName(t); if (t is TpmEnum) { var e = t as TpmEnum; foreach (var c in e.Members) { c.Name = TransConstantName(c.SpecName, c.EnclosingEnum); c.OldStyleName = TransConstantName(c.SpecName, c.EnclosingEnum, true); } } } // Then translate expressions specifying enum member values. // Note that we cannot simply iterate TpmTypes.Constants, as in many languages // the order of enum definitions is important (tracked by GeneratedEnums()/IsGenerated()). foreach (var e in TpmTypes.Get <TpmEnum>()) { // Take care Debug.Assert(!GeneratedEnums.Contains(e)); GeneratedEnums.Add(e); foreach (var c in e.Members) { c.Value = TranslateConstExpr(c.SpecValue, c.EnclosingEnum); } } // At last translate foreach (var s in TpmTypes.Get <TpmStruct>()) { foreach (var f in s.Fields) { f.TypeName = TranslateFieldType(f); } } }
public void Apply(Stack <Operand> operands) { if (Op == OpCode.Sizeof) { operands.Push((int)TpmTypes.Lookup(operands.Pop().Value).GetSize()); return; } Operand rhs = operands.Pop(); Operand lhs = operands.Pop(); operands.Push(Apply(lhs.NumericValue, rhs.NumericValue)); }
/// <summary> /// C unions of the TPM spec are translated into TypeScript classes implementing /// an interface defining the union /// </summary> void GenUnions() { var unions = TpmTypes.Get <TpmUnion>(); WriteComment("Base class for TPM union interfaces"); Write("export interface TpmUnion extends TpmMarshaller {}"); // // Union interfaces definitions // foreach (TpmUnion u in unions) { WriteComment(u); Write($"export interface {u.Name} extends TpmUnion"); TabIn("{"); Write($"GetUnionSelector(): {GetUnionSelectorType(u)};"); TabOut("}"); } // // Union factory // WriteComment("Holds static factory method for instantiating TPM unions.\n" + "Note: A wrapper class is used instead of simply static function solely " + "for the sake of uniformity with languages like C# and Java."); Write("class UnionFactory"); TabIn("{"); WriteComment("Creates specific TPM union member based on the union type and selector (tag) value"); Write("public static create(unionType: string, selector: TPM_ALG_ID | TPM_CAP | TPM_ST): any"); TabIn("{"); Write("switch (unionType) {"); foreach (TpmUnion u in unions) { TabIn($"case '{u.Name}':"); TabIn("switch (selector) {"); foreach (UnionMember m in u.Members) { string newObject = m.Type.IsElementary() ? TargetLang.Null : $"new {m.Type.Name}()"; Write($"case {m.SelectorValue.QualifiedName}: return {newObject};"); } TabOut("}", false); // inner switch Write("break;"); TabOut(); } TabIn("default:"); Write("throw new Error('UnionFactory.create(): Unknown union type ' + unionType);"); TabOut("}"); // outer switch Write("throw new Error('Unknown selector value ' + selector + ' for union ' + unionType);"); TabOut("} // create()", false); TabOut("} // class UnionFactory"); } // GenUnions()
static void FixEnumTypeCollisions() { List <TpmStruct> toAdd = new List <TpmStruct>(); for (int j = 0; j < TpmTypes.TheTypes.Count; j++) { TpmType tp = TpmTypes.TheTypes[j]; if (!(tp is TpmUnion && tp.SpecName.IsOneOf(new string[] { "TPMU_PUBLIC_ID", "TPMU_SIGNATURE" }))) { continue; } // See if we have collisions. // Collided member types are converted into derived types by adding selector name to the base // type name. Struct that became a base one inherits from all the union interfaces, while // a derived struct only inherits from the base one and implements interfaces of the unions, // of which it is a member. // Base class B provides a union interface implementation only if this union contains a member // of type B. If a union U contains members of types derived from B, then B's implementation // of U's interface methods just throws NotImplementedException exception. TpmUnion u = (TpmUnion)tp; var dict = new Dictionary <string, UnionMember>(); foreach (UnionMember m in u.Members) { string typeName = m.Type.SpecName; string selectorName = m.SelectorValue.Name; if (dict.ContainsKey(typeName)) { // Collision detected. Debug.WriteLine("Collision in {0} [{1}] -- {2}", u.Name, selectorName, typeName); TpmStruct baseStruct = (TpmStruct)TpmTypes.Lookup(typeName); AddDerivedStruct(baseStruct, m, u, "Auto-derived from " + baseStruct.SpecName + " to provide unique GetUnionSelector() implementation"); if (dict[typeName] != null) { // Create the derived structure for the first occurrence. AddDerivedStruct(baseStruct, dict[typeName], u); // But do it only once... dict[typeName] = null; } } else { dict.Add(typeName, m); } } } } // FixEnumTypeCollisions()
} // GenStruct() void GenCommands() { WriteAutoGeneratedSourceHeader(); Write("from .TpmBase import *" + "\r\n"); Write($"class Tpm(TpmBase):"); TabIn(); foreach (var req in TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest())) { GenCommand(req); } TabOut(); Write("# class Tpm"); }
static void FixStructsWithEncryptedBuffer() { foreach (var typeName in StructsWithEncryptedBuffer) { var s = (TpmStruct)TpmTypes.Lookup(typeName); var f = s.Fields[3]; Debug.Assert(f.Name.StartsWith("enc")); Debug.Assert(f.MarshalType == MarshalType.VariableLengthArray); f.MarshalType = MarshalType.EncryptedVariableLengthArray; Debug.Assert(f.SizeTagField != null); s.Fields[2] = f; s.Fields.RemoveAt(3); } }
void GenUnions() { TpmUnion[] unions = TpmTypes.Get <TpmUnion>().ToArray(); foreach (TpmUnion t in unions) { string selectorType = t.Members[0].SelectorValue.EnclosingEnum.Name; WriteComment(t); Write("public interface " + t.Name); TabIn("{"); Write($"{selectorType} GetUnionSelector();"); TabOut("}"); } Write("public abstract partial class TpmStructureBase"); TabIn("{"); Write("Type UnionElementFromSelector(Type unionInterface, object selector)"); TabIn("{"); string elseClause = ""; foreach (TpmUnion t in unions) { Write($"{elseClause}if (unionInterface == typeof({t.Name}))"); TabIn("{"); TpmEnum selectorType = null; foreach (UnionMember m in t.Members) { if (selectorType == null) { selectorType = m.SelectorValue.EnclosingEnum; Write($"switch (({selectorType.Name})selector)"); TabIn("{"); } Debug.Assert(selectorType == m.SelectorValue.EnclosingEnum); Write($"case {m.SelectorValue.QualifiedName}: return typeof({m.Type.Name});"); } TabOut("}", false); // switch TabOut("}", false); // else if elseClause = "else "; } Write("else"); TabIn("{"); Write("throw new Exception(\"Unknown union interface type \" + unionInterface.Name);"); TabOut("}", false); // else Write("throw new Exception(\"Unknown selector value\" + selector + \" for \" + unionInterface.Name + \" union\");"); TabOut("}", false); // UnionElementFromSelector TabOut("}"); // TpmStructureBase } // GenUnions()
/// <summary> /// C unions of the TPM spec are translated into Python classes implementing /// an interface defining the union /// </summary> void GenUnions() { // Base class for union interfaces TabIn("class TpmUnion(TpmMarshaller):"); WriteComment("TPM union interface"); Write("@abc.abstractmethod"); Write($"def GetUnionSelector({This}): pass # returns TPM_ALG_ID | TPM_CAP | TPM_ST"); TabOut(""); // Union interfaces definitions var unions = TpmTypes.Get <TpmUnion>(); foreach (TpmUnion u in unions) { TabIn($"class {u.Name}(TpmUnion):"); WriteComment(u); Write("pass"); TabOut(""); } // Union factory TabIn("class UnionFactory:"); Write("@staticmethod"); TabIn("def create(unionType, selector):"); WriteComment("Args:\n" + " unionType (string): union type name\n" + " selector (TPM_ALG_ID|TPM_CAP|TPM_ST): enum value\n" + " specifying the union member to instantiate"); string elIf = "if"; foreach (TpmUnion u in unions) { Write($"{elIf} unionType == '{u.Name}':"); elIf = "elif"; TabIn(); foreach (UnionMember m in u.Members) { string newObject = m.Type.IsElementary() ? TargetLang.Null : $"{m.Type.Name}()"; Write($"if selector == {m.SelectorValue.QualifiedName}: return {newObject}"); } TabOut(); } TabIn("else:"); Write("raise(Exception('UnionFactory.create(): Unrecognized union type \"{}\"'.format(unionType)))"); TabOut("raise(Exception('UnionFactory.create(): Unknown selector value \"{s}\" for union \"{u}\"'.format(s = str(selector), u = unionType)))"); TabOut("# create()", false); TabOut("# class UnionFactory()"); }
public static List <TpmNamedConstant> GetBifieldElements(TpmBitfield bf) { var elements = new List <TpmNamedConstant>(); foreach (var b in bf.Elements) { if (b.StartBit == b.EndBit) { AddBitfieldElt(elements, b.TranslatedName, 1 << b.StartBit, b.Comment, b.OldStyleName); } else // multibit members of a bitfield { string typeName = b.Name; if (TpmTypes.Contains(typeName)) { // Type typeName defines allowed values for this multi-bit field var e = TpmTypes.Lookup(typeName) as TpmEnum; if (e != null) { foreach (var v in e.Members) { AddBitfieldElt(elements, v.Name, v.NumericValue << b.EndBit, v.Comment); } } } // Multi-bit bitfield 'name' is additionally represented by several enumerators: // name_BIT_MASK - bit mask selecting all bits of the field // name_BIT_OFFSET - offset of the field's low order bit // name_BIT_LENGTH - number of bits in the field string nameBase = b.Name.Contains("_") ? TargetLang.NameToDotNet(b.Name) : b.Name; int len = b.StartBit - b.EndBit + 1; var suff = TargetLang.DotNet ? new string[] { "BitMask", "BitOffset", "BitLength" } : new string[] { "_BIT_MASK", "_BIT_OFFSET", "_BIT_LENGTH" }; AddBitfieldElt(elements, nameBase + suff[0], ((1 << len) - 1) << b.EndBit, b.Comment, null, true); AddBitfieldElt(elements, nameBase + suff[1], b.EndBit, null, null, true); AddBitfieldElt(elements, nameBase + suff[2], len, null, null, true); if (TargetLang.DotNet && bf.Name == "LocalityAttr") { // For backward compatibility for (int i = 0; i < len; ++i) { AddBitfieldElt(elements, $"{nameBase}Bit{i}", 1 << (b.EndBit + i), "", null, true); } } } // multibit members of a bitfield } return(elements); }
void WriteAutoGeneratedSourceHeader() { TpmNamedConstant ver = TpmTypes.LookupConstant("TPM_SPEC_VERSION"); Write("\"\"\"\r\n" + " * Copyright(c) Microsoft Corporation. All rights reserved. \r\n" + " * Licensed under the MIT License. \r\n" + " * See the LICENSE file in the project root for full license information. \r\n" + "\"\"\"\r\n" + "\r\n" + "\"\"\"\r\n" + " * This file is automatically generated from the TPM 2.0 rev. " + (ver.NumericValue / 100.0).ToString("0.00") + " specification documents.\r\n" + " * Do not edit it directly.\r\n" + "\"\"\"\r\n"); }
} // GenStruct() void GenCommands() { WriteAutoGeneratedSourceHeader(); Write("import * as tt from \"./TpmTypes.js\";\r\n" + "import { TpmBase, TpmError } from \"./TpmBase.js\";\r\n" + "import { TpmBuffer } from \"./TpmMarshaller.js\";\r\n" + "\r\n"); Write($"export class Tpm extends TpmBase"); TabIn("{"); foreach (var req in TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest())) { GenCommand(req); } TabOut("} // class Tpm", false); } // GenCommands()
static List <TpmStruct> GetUnionMemberStructures(UnionField uf) { var unionList = new List <TpmStruct>(); foreach (var s in TpmTypes.Get <TpmStruct>().Where(s => !s.IsCmdStruct())) { foreach (TpmUnion u in s.ContainingUnions) { if (u.Name == uf.TypeName) { unionList.Add(s); } } } return(unionList); }
} // GenMarshalingMethod() // Generates implementation of the TPM structures methods void GenStructsCpp() { foreach (var s in TpmTypes.Get <TpmStruct>()) { if (IsTypedefStruct(s)) { continue; } // Marshaling GenMarshalingMethod(true, s); GenMarshalingMethod(false, s); GenMarshalingMethod(true, s, false, true); GenMarshalingMethod(false, s, false, true); } } // GenStructsCpp()
public static void DoFixups() { // Many TPM structs represent a length-prefixed array or structure. // When such struct is a fields of another (enclosing) structure, get rid of the struct // wrapper and place the payload array/struct directly as the member of the enclosing struct. FixTpm2bStructs(); FlattenTaggedStructures(); FixStructsWithEncryptedBuffer(); FlattenLists(); // This command allows session based encryption. foreach (var s in TpmTypes.Get <TpmStruct>().Where(s => s.IsCmdStruct())) { if (s.Fields.Count > s.NumHandles && s.Fields[s.NumHandles].MarshalType.IsOneOf(MarshalType.ArrayCount, MarshalType.LengthOfStruct)) { // This command allows session based encryption. Debug.Assert(s.Fields.Count > s.NumHandles + 1); var sizeField = s.Fields[s.NumHandles]; var sizedField = s.Fields[s.NumHandles + 1]; var cmdInfo = s.Info as CmdStructInfo; cmdInfo.SessEncSizeLen = sizeField.Type.GetSize(); cmdInfo.SessEncValLen = sizeField.MarshalType == MarshalType.LengthOfStruct ? 1 : sizedField.Type.GetSize(); } } TpmStruct[] symDefs = { (TpmStruct)TpmTypes.Lookup("TPMT_SYM_DEF"), (TpmStruct)TpmTypes.Lookup("TPMT_SYM_DEF_OBJECT") }; var fieldTypes = new string[] { "TPM_ALG_ID", "UINT16", "TPM_ALG_ID" }; Debug.Assert(symDefs[0].Fields.Count == symDefs[1].Fields.Count && symDefs[0].Fields.Count == fieldTypes.Length); for (int i = 0; i < fieldTypes.Length; ++i) { foreach (var sd in symDefs) { sd.Fields[i].MarshalType = MarshalType.Normal; sd.Fields[i].Type = TpmTypes.Lookup(fieldTypes[i]); } } symDefs[0].Fields[0].Attrs = symDefs[1].Fields[0].Attrs |= StructFieldAttr.TermOnNull; FixEnumTypeCollisions(); }
} // GenStructsCpp() void GenCommandDispatchers() { var cmdRequestStructs = TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest()); foreach (var s in cmdRequestStructs) { GenCommandDispatcher(s, CommandFlavor.Synch); } foreach (var s in cmdRequestStructs) { GenCommandDispatcher(s, CommandFlavor.AsyncCommand); } foreach (var s in cmdRequestStructs) { GenCommandDispatcher(s, CommandFlavor.AsyncResponse); } } // GenCommandDispatchers()
public UnionMember(string typeName, string fieldName, string selectorName, string comment) : base(typeName, fieldName, comment) { Match m; if ((m = Regex.Match(fieldName, @"^(?<name>\w+)\s*\[?(?<val>[^\]]*)\)?]?")).Success) { Name = m.Groups["name"].ToString(); Debug.Assert(Name.Length > 0); string arraySize = m.Groups["val"].ToString(); if (arraySize != "") { ArraySize = arraySize; } } SelectorValue = TpmTypes.LookupConstant(selectorName); }
static void TweakSymDefStructFieldNames(bool dotNet) { var sd = (TpmStruct)TpmTypes.Lookup("TPMT_SYM_DEF"); var sdo = (TpmStruct)TpmTypes.Lookup("TPMT_SYM_DEF_OBJECT"); for (int i = 0; i < sd.Fields.Count; ++i) { Debug.Assert(sd.Fields[i].Name == sdo.Fields[i].Name); if (dotNet) { sd.Fields[i].Name = sdo.Fields[i].Name = Helpers.Capitalize(sd.Fields[i].Name); } else { sd.Fields[i].Name = sdo.Fields[i].Name = sd.Fields[i].Name.ToLower(); } } }
internal override void Generate() { // Go through the types generating code foreach (var t in TpmTypes.Get <TpmType>()) { if (t is TpmEnum) { GenEnum(t as TpmEnum); } else if (t is TpmBitfield) { GenBitfield(t as TpmBitfield); } else if (t is TpmUnion) { GenUnion(t as TpmUnion); } else if (t is TpmStruct) { GenStruct(t as TpmStruct); } else { continue; } string typeName = t.Name; WriteDef(GetJavaFileName(typeName), null, false); } GenUnionFactory(); WriteDef(GetJavaFileName("UnionFactory"), null, false); // Now generate the TPM methods GenCommands(); WriteDef(GetJavaFileName(), null, true); foreach (var t in TpmTypes.TheTypes.Where(t => !t.Implement)) { string typeName = t.Name; File.Delete(GetJavaFileName(typeName)); } }
public static void AddDerivedStruct(TpmStruct baseStruct, UnionMember curMember, TpmUnion curUnion, string comment = null) { string baseTypeName = baseStruct.SpecName; string newTypeName = baseTypeName + "_" + RemoveEnumPrefix(curMember.SelectorValue.SpecName, curMember.SelectorValue.EnclosingEnum.SpecName); if (!TpmTypes.Contains(newTypeName)) { var newStruct = new TpmStruct(newTypeName, comment ?? "Auto-derived from " + baseTypeName, baseStruct); TpmTypes.Add(newStruct); } var s = (TpmStruct)TpmTypes.Lookup(newTypeName); s.RegisterContainingUnion(curUnion); // Fix up the union field curMember.Type = s; }
} // GenEnumMap() void GenUnionFactory() { var unions = TpmTypes.Get <TpmUnion>(); WriteComment("Holds static factory method for instantiating TPM unions.\n" + "Note: A wrapper class is used instead of simply static function solely " + "for the sake of uniformity with languages like C# and Java."); Write("struct UnionFactory"); TabIn("{"); WriteComment("Creates specific TPM union member based on the union type and selector (tag) value"); Write("template<class U, typename S>"); Write("static void Create(shared_ptr<U>& u, S selector) // S = TPM_ALG_ID | TPM_CAP | TPM_ST"); TabIn("{"); Write("size_t unionType = typeid(U).hash_code();"); string elsePref = ""; foreach (TpmUnion u in unions) { TabIn($"{elsePref}if (unionType == typeid({u.Name}).hash_code())"); elsePref = "else "; TabIn("switch (selector) {"); foreach (UnionMember m in u.Members) { //if (m.SelectorValue.Name.StartsWith("TPM_ALG_ANY")) continue; string newObj = m.Type.IsElementary() ? "nullptr" : $"new {m.Type.Name}()"; Write($"case {m.SelectorValue.QualifiedName}: new (&u) shared_ptr<{u.Name}>({newObj}); return;"); } TabOut("}", false); // switch (selector) TabOut(); // if / else if } TabIn("else"); Write("throw runtime_error(\"UnionFactory::Create(): Unknown union type \" + string(typeid(U).name()));"); TabOut("throw runtime_error(\"Unknown selector value\" + to_string(selector) + \" for union \" + string(typeid(U).name()));"); TabOut("} // Create()"); TabOut("}; // class UnionFactory"); }