Beispiel #1
0
        /// <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));
        }
Beispiel #2
0
        } // 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()
Beispiel #3
0
        } // 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()
Beispiel #4
0
        } // 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()
Beispiel #5
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()
Beispiel #6
0
        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()