protected void WriteComment(TpmField f) { WriteComment(f.Comment, f.Type); }
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()