/// <param name="selVal"> Upon return set to the value (qualified enum memeber) of the selector (or null). </param> /// <returns> Union selector type name if 's' is a member of a tagged union. Otherwise null. </returns> public static string GetUnionMemberSelectorInfo(TpmStruct s, out string selVal) { selVal = null; if (s.IsCmdStruct() || s.ContainingUnions.Count == 0) { return(null); } // If a struct is a member of multiple unions, all of them are expected to use the same selector value TpmUnion u = s.ContainingUnions.ElementAt(0); selVal = s.SpecName == TpmTypes.EmptyUnionBaseName ? TpmTypes.AlgNull : u.GetMemberOfType(s).SelectorValue.QualifiedName; return(GetUnionSelectorType(u)); }
} // GenMarshalingMethod() /// <summary> /// Structures in C are classes in TypeScript /// </summary> /// <param name="s"></param> void GenStruct(TpmStruct s) { bool hasBase = s.DerivedFrom != null; string className = s.Name; string classBases = hasBase ? s.DerivedFrom.Name : !s.IsCmdStruct() ? "TpmStructure" : s.Info.IsRequest() ? "ReqStructure" : "RespStructure"; // If this struct is not derived from another one and is a member of one or more unions, // it must implement the corresponding union interfaces if (!s.IsCmdStruct() && !hasBase) { string unionInterfaces = string.Join(", ", s.ContainingUnions.Select(u => u.Name)); if (unionInterfaces != "") { classBases += ", " + unionInterfaces; } } // Class header TabIn($"class {className} ({classBases}):"); // Javadoc comment for the data structure string annotation = s.Comment + eol; var fields = s.FieldHolder.NonTagFields; if (fields.Length != 0) { annotation += eol + "Attributes:" + eol; foreach (var f in fields) { annotation += GetParamComment(f, " ", " ") + eol; } } // // Field defining constructor // if (fields.Count() == 0) { TabIn($"def __init__({This}):"); WriteComment(annotation); Write("pass"); TabOut(); } else { string ctorParams = string.Join(", ", fields.Select(f => f.Name + $" = {f.GetInitVal()}")); TabIn($"def __init__({This}, {ctorParams}):"); WriteComment(annotation); // If a non-trivial base class is present, all member fields are contained there, // so just pass through the initialization parameters if (hasBase) { string baseInitParams = string.Join(", ", fields.Select(f => f.Name)); //Write($"{s.DerivedFrom}.__init__({baseInitParams})"); Write($"super({className}, {This}).__init__({baseInitParams})"); } else { foreach (var f in fields) { Write($"{ThisMember}{f.Name} = {f.Name}"); } } TabOut(); // // Named union tag getters (instead of the corresponding fields in the TPM 2.0 spec) // foreach (var sel in s.TagFields) { if (sel.MarshalType != MarshalType.UnionSelector) { continue; } var unionField = sel.RelatedUnion; var u = (TpmUnion)unionField.Type; Write(""); Write("@property"); TabIn($"def {sel.Name}({This}): # {sel.TypeName}"); WriteComment(sel.Comment); if (u.NullSelector == null) { Write($"return {unionField.Name}.GetUnionSelector()"); } else { Write($"return {unionField.Name}.GetUnionSelector() if {unionField.Name}" + $" else {u.NullSelector.QualifiedName}"); } TabOut(); } foreach (var f in fields) { if (f.MarshalType != MarshalType.UnionObject) { continue; } var u = (TpmUnion)f.Type; var sel = (f as UnionField).UnionSelector; } } GenGetUnionSelector(s); // // Marshaling // GenMarshalingMethod(true, s); GenMarshalingMethod(false, s); Write(""); Write($"@staticmethod"); TabIn("def fromTpm(buf):"); WriteComment($"Returns new {className} object constructed from its marshaled representation in the given TpmBuffer buffer"); Write($"return buf.createObj({className})"); TabOut(""); Write($"@staticmethod"); TabIn("def fromBytes(buffer):"); WriteComment($"Returns new {className} object constructed from its marshaled representation in the given byte buffer"); Write($"return TpmBuffer(buffer).createObj({className})"); TabOut(); var info = s.IsCmdStruct() ? s.Info as CmdStructInfo : null; if (info != null && (info.NumHandles != 0 || info.SessEncSizeLen != 0)) { if (info.NumHandles != 0) { Write(""); Write($"def numHandles({This}): return {info.NumHandles}"); if (info.IsRequest()) { string handles = string.Join(", ", s.Fields.Take(info.NumHandles).Select(f => ThisMember + f.Name)); Write(""); Write($"def numAuthHandles({This}): return {info.NumAuthHandles}"); Write(""); Write($"def getHandles({This}): return [{handles}]"); } else { Debug.Assert(info.NumHandles == 1 && info.NumAuthHandles == 0); Write(""); Write($"def getHandle({This}): return {ThisMember}{s.Fields[0].Name}"); Write(""); Write($"def setHandle({This}, h): {ThisMember}{s.Fields[0].Name} = h"); } } if (info.SessEncSizeLen != 0) { Debug.Assert(info.SessEncValLen != 0); Write(""); Write($"def sessEncInfo({This}): return SessEncInfo({info.SessEncSizeLen}, {info.SessEncValLen})"); } } // // Custom members // InsertSnip(s.Name); TabOut($"# {className}"); } // GenStruct()
} // GenMarshalingMethod() /// <summary> /// Structures in C are classes in TypeScript /// </summary> /// <param name="s"></param> void GenStruct(TpmStruct s) { bool hasBase = s.DerivedFrom != null; string className = s.Name; string classBases = hasBase ? s.DerivedFrom.Name : !s.IsCmdStruct() ? "TpmStructure" : s.Info.IsRequest() ? "ReqStructure" : "RespStructure"; // If this struct is not derived from another one and is a member of one or more unions, // it must implement the corresponding union interfaces if (!s.IsCmdStruct() && !hasBase) { string unionInterfaces = string.Join(", ", s.ContainingUnions.Select(u => u.Name)); if (unionInterfaces != "") { classBases += " implements " + unionInterfaces; } } // Javadoc comment for the data structure WriteComment(s); // Class header Write($"export class {className} extends {classBases}"); TabIn("{"); // In TypeScript, member fields declaration is melded with member-wise constructor // that also playe the role of the default one // // Field defining constructor // var fields = s.FieldHolder.NonTagFields; if (fields.Count() == 0) { Write("constructor() { super(); }"); } else { Write("constructor("); TabIn(); // If a non-trivial base class is present, all member fields are contained there, // so just pass through the initialization parameters string ctrParamQualifier = hasBase ? "" : "public "; string baseIntializers = ""; foreach (var f in fields) { // Javadoc comment for the member/constructor parameter. // Add a list of data structures implementing the interface of a union parameters. WriteComment(f); string comma = Separator(f, fields, ", "); Write($"{ctrParamQualifier}{f.Name}: {f.TypeName} = {f.GetInitVal()}{comma}"); if (hasBase) { baseIntializers += f.Name + comma; } } TabOut($") {{ super({baseIntializers}); }}"); // // Named union tag getters (instead of the corresponding fields in the TPM 2.0 spec) // foreach (var sel in s.TagFields) { if (sel.MarshalType != MarshalType.UnionSelector) { continue; } var u = (TpmUnion)sel.RelatedUnion.Type; string unionField = ThisMember + sel.RelatedUnion.Name; WriteComment(sel); Write($"get {sel.Name}(): {sel.TypeName} {{ ", false); if (u.NullSelector == null) { Write($"return {unionField}.GetUnionSelector(); }}"); } else { Write($"return {unionField} ? {unionField}.GetUnionSelector()" + $" : {u.NullSelector.QualifiedName}; }}"); } } } // // Union interface: TpmUnion.GetUnionSelector() // GenGetUnionSelector(s); // // Marshaling // GenMarshalingMethod(true, s); GenMarshalingMethod(false, s); WriteComment("Static marshaling helper"); Write($"public static fromTpm(buf: TpmBuffer) : {className}"); TabIn("{"); Write($"return buf.createObj({className});"); TabOut("}"); WriteComment("Static marshaling helper"); Write($"public static fromBytes(buffer: any) : {className}"); TabIn("{"); Write($"return new TpmBuffer(buffer).createObj({className});"); TabOut("}"); var info = s.IsCmdStruct() ? s.Info as CmdStructInfo : null; if (info != null && (info.NumHandles != 0 || info.SessEncSizeLen != 0)) { if (info.NumHandles != 0) { Write($"numHandles(): number {{ return {info.NumHandles}; }}"); if (info.IsRequest()) { string handles = string.Join(", ", s.Fields.Take(info.NumHandles).Select(f => ThisMember + f.Name)); Write($"numAuthHandles(): number {{ return {info.NumAuthHandles}; }}"); Write($"getHandles(): TPM_HANDLE[] {{ return [{handles}]; }}"); } else { Debug.Assert(info.NumHandles == 1 && info.NumAuthHandles == 0); Write($"getHandle(): TPM_HANDLE {{ return {ThisMember}{s.Fields[0].Name}; }}"); Write($"setHandle(h: TPM_HANDLE): void {{ {ThisMember}{s.Fields[0].Name} = h; }}"); } } if (info.SessEncSizeLen != 0) { Debug.Assert(info.SessEncValLen != 0); Write(""); Write($"sessEncInfo(): SessEncInfo {{ return new SessEncInfo({info.SessEncSizeLen}, {info.SessEncValLen}); }}"); } } // // Custom members // InsertSnip(s.Name); TabOut($"}} // {className}"); } // GenStruct()
} // GenMarshalingMethod() void GenStruct(TpmStruct s) { bool hasBase = s.DerivedFrom != null; string className = s.Name; string classBases = hasBase ? s.DerivedFrom.Name : !s.IsCmdStruct() ? "TpmStructure" : s.Info.IsRequest() ? "ReqStructure" : "RespStructure"; // If this struct is not derived from another one and is a member of one or more unions, // it must implement the corresponding union interfaces if (!s.IsCmdStruct() && !hasBase) { string unionInterfaces = string.Join(", ", s.ContainingUnions.Select(u => u.Name)); if (unionInterfaces != "") { classBases += " implements " + unionInterfaces; } } // Javadoc comment for the data structure WriteComment(s); // Class header Write($"public class {className} extends {classBases}"); TabIn("{"); // // Fields // Debug.Assert(s.Fields.Count == 0 || !hasBase); foreach (var f in s.NonSizeFields) { if (f.MarshalType == MarshalType.ConstantValue) { continue; } WriteComment(f); if (f.MarshalType == MarshalType.UnionSelector) { var unionField = f.RelatedUnion; var u = (TpmUnion)unionField.Type; Write($"public {f.TypeName} {f.Name}() {{ ", false); if (u.NullSelector == null) { Write($"return {unionField.Name}.GetUnionSelector(); }}"); } else { Write($"return {unionField.Name} != null ? {unionField.Name}.GetUnionSelector()" + $" : {u.NullSelector.QualifiedName}; }}"); } } else { Write($"public {f.TypeName} {f.Name};"); } } // // Default constructor // var fieldsToInit = s.NonDefaultInitFields; Write(""); Write($"public {className}()", false); if (fieldsToInit.Count() == 0) { Write(" {}"); } else if (fieldsToInit.Count() == 1) { var f = fieldsToInit[0]; Write($" {{ {f.Name} = {f.GetInitVal()}; }}"); } else { TabIn("{"); foreach (StructField f in fieldsToInit) { Write($"{f.Name} = {f.GetInitVal()};"); } TabOut("}"); } // // Member-wise constructor // var ctorParams = s.FieldHolder.NonTagFields; if (!s.Info.IsResponse() && ctorParams.Count() != 0) { // Javadoc comments (note that we provide a bit more info for union parameters) string javaDocComment = ""; foreach (var p in ctorParams) { javaDocComment += GetParamComment(p, "_") + eol; } WriteComment(javaDocComment); string ctorOpen = $"public {className}("; string ctorParamList = string.Join(", ", ctorParams.Select(p => p.TypeName + " _" + p.Name)); Write(ctorOpen + ctorParamList + ")", false); if (hasBase) { if (ctorParams.Length == 1) { Write($" {{ super(_{ctorParams[0].Name}); }}"); } else { string ctorParamNamesList = string.Join(", ", ctorParams.Select(p => "_" + p.Name)); TabIn("{"); Write($"super({ctorParamNamesList});"); TabOut("}"); } } else if (ctorParams.Length == 1) { var p = ctorParams[0]; Write($" {{ {p.Name} = _{p.Name}; }}"); } else { TabIn("{"); foreach (var p in ctorParams) { // We turn shorts into ints in constructor args, to allow external API users // avoid incessant casting. Instead the cast is hidden in the constructor body. // Note that we cannot change the type of the corresponding members, as it is // dictated by the TPM 2.0 spec. Write($"{p.Name} = _{p.Name};"); } TabOut("}"); } } // // Union interface: TpmUnion.GetUnionSelector() // GenGetUnionSelector(s); // // Marshaling // GenMarshalingMethod(true, s); GenMarshalingMethod(false, s); WriteComment("@deprecated Use {@link #toBytes()} instead\n" + "@return Wire (marshaled) representation of this object"); Write("public byte[] toTpm () { return toBytes(); }"); WriteComment("Static marshaling helper\n" + "@param byteBuf Wire representation of the object\n" + "@return New object constructed from its wire representation"); Write($"public static {className} fromBytes (byte[] byteBuf) "); TabIn("{"); Write($"return new TpmBuffer(byteBuf).createObj({className}.class);"); TabOut("}"); WriteComment("@deprecated Use {@link #fromBytes(byte[])} instead\n" + "@param byteBuf Wire representation of the object\n" + "@return New object constructed from its wire representation"); Write($"public static {className} fromTpm (byte[] byteBuf) {{ return fromBytes(byteBuf); }}"); WriteComment("Static marshaling helper\n" + "@param buf Wire representation of the object\n" + "@return New object constructed from its wire representation"); Write($"public static {className} fromTpm (TpmBuffer buf) "); TabIn("{"); Write($"return buf.createObj({className}.class);"); TabOut("}"); Write("@Override"); Write("public String toString()"); TabIn("{"); Write($"TpmStructurePrinter _p = new TpmStructurePrinter(\"{s.Name}\");"); Write("toStringInternal(_p, 1);"); Write("_p.endStruct();"); Write("return _p.toString();"); TabOut("}", false); if (s.Fields.Count() > 0) { Write("@Override"); Write("public void toStringInternal(TpmStructurePrinter _p, int d)"); TabIn("{"); foreach (StructField f in ctorParams) { Write($"_p.add(d, \"{f.TypeName}\", \"{f.Name}\", {f.Name});"); } TabOut("}", false); } var info = s.IsCmdStruct() ? s.Info as CmdStructInfo : null; if (info != null && (info.NumHandles != 0 || info.SessEncSizeLen != 0)) { if (info.NumHandles != 0) { Write("@Override"); Write($"public int numHandles() {{ return {info.NumHandles}; }}"); if (info.IsRequest()) { string handles = string.Join(", ", s.Fields.Take(info.NumHandles).Select(f => ThisMember + f.Name)); Write("@Override"); Write($"public int numAuthHandles() {{ return {info.NumAuthHandles}; }}"); Write("@Override"); Write($"public TPM_HANDLE[] getHandles() {{ return new TPM_HANDLE[] {{{handles}}}; }}"); } else { Debug.Assert(info.NumHandles == 1 && info.NumAuthHandles == 0); Write("@Override"); Write($"public TPM_HANDLE getHandle() {{ return {ThisMember}{s.Fields[0].Name}; }}"); Write("@Override"); Write($"public void setHandle(TPM_HANDLE h) {{ {ThisMember}{s.Fields[0].Name} = h; }}"); } } if (info.SessEncSizeLen != 0) { Debug.Assert(info.SessEncValLen != 0); Write("@Override"); Write($"public SessEncInfo sessEncInfo() {{ return new SessEncInfo({info.SessEncSizeLen}, {info.SessEncValLen}); }}"); } } InsertSnip(s.Name); TabOut("}", false); } // GenStruct()
void GenStructDecl(TpmStruct s) { bool hasBase = s.DerivedFrom != null; // Has a non-trivial base class? string className = s.Name; if (IsTypedefStruct(s)) { Debug.Assert(s.Fields.Count == 0); WriteComment(s); Write($"typedef {s.DerivedFrom.Name} {className};"); Write(""); return; } string classBases = hasBase ? s.DerivedFrom.Name : !s.IsCmdStruct() ? "TpmStructure" : s.Info.IsRequest() ? "ReqStructure" : "RespStructure"; string virt = ""; // If this struct is not derived from another one and is a member of one or more unions, // it must implement the corresponding union interfaces if (!s.IsCmdStruct() && !hasBase && s.ContainingUnions.Count > 0) { foreach (var u in s.ContainingUnions) { classBases += ", public " + u.Name; } virt = "virtual "; } WriteComment(s); Write($"class _DLLEXP_ {className} : public {virt}{classBases}"); Write("{"); TabIn("public:"); // // Fields // TpmField conversionSource = null; foreach (var f in s.NonSizeFields) { if (f.MarshalType == MarshalType.ConstantValue) { // No member field for a constant tag continue; } WriteComment(f); if (f.MarshalType == MarshalType.UnionSelector) { var unionField = f.RelatedUnion; var u = (TpmUnion)unionField.Type; Write($"public: {f.TypeName} {f.Name}() const {{ ", false); if (u.NullSelector == null) { Write($"return {unionField.Name}->GetUnionSelector(); }}"); } else { Write($"return {unionField.Name} ? {unionField.Name}->GetUnionSelector()" + $" : {u.NullSelector.QualifiedName}; }}"); } continue; } Write($"{TransType(f)} {f.Name};"); } TabOut(""); TabIn("public:"); // // Default constructor // var fieldsToInit = s.NonDefaultInitFields; Write($"{className}()", false); if (fieldsToInit.Count() == 0) { Write(" {}"); } else if (fieldsToInit.Count() == 1) { Write($" {{ {fieldsToInit[0].Name} = {fieldsToInit[0].GetInitVal()}; }}"); } else { TabIn("{"); foreach (StructField f in fieldsToInit) { Write($"{f.Name} = {f.GetInitVal()};"); } TabOut("}"); } // // Member-wise constructor // var ctorParams = s.FieldHolder.NonTagFields; if (!s.Info.IsResponse() && ctorParams.Count() != 0) { string baseClass = hasBase ? s.DerivedFrom.Name : "TpmStructure"; string ctorParamList = string.Join(", ", ctorParams.Select(p => $"{CtorParamTypeFor(p)} _{p.Name}")); Write($"{className}({ctorParamList})"); if (hasBase) { string ctorParamNamesList = string.Join(", ", ctorParams.Select(p => "_" + p.Name)); Write($" : {baseClass}({ctorParamNamesList})"); } else { string memInitList = string.Join(", ", ctorParams.Select(p => p.Type is TpmUnion ? $"{p.Name}(dynamic_cast<{p.Type.Name}*>(_{p.Name}.Clone()))" : $"{p.Name}(_{p.Name})" )); Write($" : {memInitList}"); } Write("{}"); } if (conversionSource != null) { Write(""); Write($"operator ByteVec&() {{ return {conversionSource.Name}; }}"); Write($"operator const ByteVec&() const {{ return {conversionSource.Name}; }}"); } // // Union interface: TpmUnion.GetUnionSelector() // GenGetUnionSelector(s); // // Marshaling // Write(""); GenMarshalingMethod(true, s, true); GenMarshalingMethod(false, s, true); string comment = AsSummary("Static marshaling helper"); WriteComment(comment); Write($"static {className} fromTpm(TpmBuffer& buf) {{ return buf.createObj<{className}>(); }}"); WriteComment(comment); Write($"static {className} fromBytes(const ByteVec& buf) {{ return TpmStructure::fromBytes<{className}>(buf); }}"); // // Serialization // Write(""); Write($"virtual const char* TypeName () const {{ return \"{className}\"; }}"); Write(""); Write("using TpmStructure::Serialize;"); Write("using TpmStructure::Deserialize;"); GenMarshalingMethod(true, s, true, true); GenMarshalingMethod(false, s, true, true); // // Cloning and metadata // Write(""); Write($"virtual TpmStructure* Clone() const {{ return new {className}(*this); }}"); var info = s.IsCmdStruct() ? s.Info as CmdStructInfo : null; if (info != null && (info.NumHandles != 0 || info.SessEncSizeLen != 0)) { TabOut(""); TabIn("protected:"); if (info.NumHandles != 0) { Write($"virtual uint16_t numHandles() const {{ return {info.NumHandles}; }}"); if (info.IsRequest()) { string handles = string.Join(", ", s.Fields.Take(info.NumHandles).Select(f => f.Name)); Write($"virtual uint16_t numAuthHandles() const {{ return {info.NumAuthHandles}; }}"); Write($"virtual vector<TPM_HANDLE> getHandles() const {{ return {{{handles}}}; }}"); } else { Debug.Assert(info.NumHandles == 1 && info.NumAuthHandles == 0); Write($"virtual TPM_HANDLE getHandle() const {{ return {s.Fields[0].Name}; }}"); Write($"virtual void setHandle(const TPM_HANDLE& h) {{ {s.Fields[0].Name} = h; }}"); } } if (info.SessEncSizeLen != 0) { Debug.Assert(info.SessEncValLen != 0); Write(""); Write($"virtual SessEncInfo sessEncInfo() const {{ return {{{info.SessEncSizeLen}, {info.SessEncValLen}}}; }}"); } } InsertSnip(s.Name); TabOut($"}}; // class {className}"); } // GenStruct()
void GenStructure(TpmStruct s) { bool hasBase = s.DerivedFrom != null; // Has a non-trivial base class? string className = s.Name; string classBases = hasBase ? s.DerivedFrom.Name : "TpmStructureBase"; // Here "implements" is as opposed to "inherits and overrides" bool implementsUnionInterfaces = !s.IsCmdStruct() && !hasBase && s.ContainingUnions.Count > 0; Debug.Assert(s.DerivedFrom == null || s.DerivedFrom.ContainingUnions.Count >= s.ContainingUnions.Count); if (implementsUnionInterfaces) { foreach (TpmUnion u in s.ContainingUnions) { classBases += ", " + u.Name; } } WriteComment(s); Write("[DataContract]"); var knownTypes = GetKnownTypes(s); foreach (TpmType kt in knownTypes) { Write($"[KnownType(typeof({kt.Name}))]"); } string specName = s.Info.IsRequest() ? s.SpecName.Substring(5).Replace("_REQUEST", "_In") : s.Info.IsResponse() ? s.SpecName.Replace("Response", "_Out") : s.SpecName; Write($"[SpecTypeName(\"{specName}\")]"); Write($"public partial class {className}: {classBases}"); TabIn("{"); if (s.DerivedFrom != null) { Debug.Assert(!s.IsCmdStruct()); //--------------------------------------- // Constructors var fields = new List <StructField>(); TpmStruct b = s; do { fields.AddRange(b.NonTagFields); b = b.DerivedFrom; } while (b != null); // Default constructor Write($"public {className}() {{}}"); Write(""); if (fields.Count != 0) { // Copy-constructor WriteLine("public {0}({0} _{0}) : base(_{0}) {{}}", className); Write(""); // Member-wise constructor GenMemeberwiseCtorPrototype(className, fields); if (fields.Count == 1) { Write($" : base(_{fields.First().Name}) {{}}"); } else { string baseInitList = string.Join(", ", fields.ConvertAll(f => "_" + f.Name)); Write(""); Write($" : base({baseInitList})"); Write("{}"); } Write(""); } GenGetUnionSelector(s, implementsUnionInterfaces); GenCloningMethods(s.Name); // end of class TabOut("}"); return; } // if (s.DerivedFrom != null) // // Member fields // bool onlyStaticFields = true; int idx = 0; foreach (StructField f in s.Fields) { var tag = f.SizeTagField; if (f.SizedField == null) { WriteComment(f); WriteConstraints(f); } onlyStaticFields = false; switch (f.MarshalType) { case MarshalType.ArrayCount: case MarshalType.LengthOfStruct: --idx; break; case MarshalType.UnionSelector: { Debug.Assert(f.RelatedUnion.MarshalType == MarshalType.UnionObject); Debug.Assert(f.RelatedUnion.UnionSelector == f); var unionField = f.RelatedUnion; var u = (TpmUnion)unionField.Type; Write($"[MarshalAs({idx}, MarshalType.UnionSelector)]"); TabIn($"public {f.TypeName} {f.Name} {{"); if (u.NullSelector == null) { Write($"get {{ return {unionField.Name}.GetUnionSelector(); }}"); } else { Write($"get {{ return {unionField.Name} != null ? {unionField.Name}.GetUnionSelector() : {u.NullSelector.QualifiedName}; }}"); } TabOut("}"); // property break; } case MarshalType.Normal: case MarshalType.SizedStruct: { if (tag == null) { Write($"[MarshalAs({idx})]"); } else { Write($"[MarshalAs({idx}, MarshalType.SizedStruct, \"{tag.Name}\", {tag.Type.GetSize()})]"); } WriteFieldDef(f, " { get; set; }"); break; } case MarshalType.UnionObject: { UnionField fx = (UnionField)f; Write($"[MarshalAs({idx}, MarshalType.Union, \"{fx.UnionSelector.Name}\")]"); WriteFieldDef(f, " { get; set; }"); break; } case MarshalType.VariableLengthArray: case MarshalType.SpecialVariableLengthArray: { string marshalType = Enum.GetName(typeof(MarshalType), f.MarshalType); Write($"[MarshalAs({idx}, MarshalType.{marshalType}, \"{tag.Name}\", {tag.Type.GetSize()})]"); WriteFieldDef(f); break; } case MarshalType.EncryptedVariableLengthArray: { Write($"[MarshalAs({idx}, MarshalType.EncryptedVariableLengthArray)]"); WriteFieldDef(f); break; } case MarshalType.ConstantValue: { string val = TargetLang.TranslateConstExpr(f.Domain[0, Constraint.Type.Single]); Write($"[MarshalAs({idx})]"); WriteFieldDef(f, $" = {val};"); break; } default: throw new Exception(); } ++idx; } // foreach field if (onlyStaticFields && s.Fields.Count > 0) { // end of class TabOut("}"); return; } // Default constructor var fieldsToInit = s.NonDefaultInitFields; Write(""); Write($"public {className}()", false); if (fieldsToInit.Count() == 0) { Write(" {}"); } else if (fieldsToInit.Count() == 1) { var f = fieldsToInit[0]; Write($" {{ {f.Name} = {f.GetInitVal()}; }}"); } else { TabIn("{"); foreach (StructField f in fieldsToInit) { Write($"{f.Name} = {f.GetInitVal()};"); } TabOut("}"); } // Copy constructor if (!s.Info.IsRequest()) { var fields = s.NonTagFields; if (fields.Count() != 0) { Write(""); Write($"public {className}({className} src)", false); if (fields.Count() == 1 && s.SpecName != "TPM_HANDLE") { string field = fields.First().Name; Write($" {{ {field} = src.{field}; }}"); } else { Write(""); TabIn("{"); foreach (StructField f in fields) { Write($"{f.Name} = src.{f.Name};"); } // special case if (s.SpecName == "TPM_HANDLE") { Write("Auth = src.Auth;"); TabIn("if (src.Name != null)"); Write("Name = Globs.CopyData(src.Name);"); TabOut(); } TabOut("}"); } } } // Member-wise constructor if (!s.Info.IsResponse()) { var fields = s.NonTagFields; if (fields.Count() != 0) { GenMemeberwiseCtorPrototype(className, fields); if (fields.Count() == 1) { string fName = fields.First().Name; Write($" {{ {fName} = _{fName}; }}"); } else { TabIn("{"); foreach (StructField f in fields) { Write($"{f.Name} = _{f.Name};"); } TabOut("}"); } } } GenGetUnionSelector(s); GenCloningMethods(s.Name); TabOut("}"); // end of class } // GenStructure()