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