Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        // The spec uses these two sorts of tagged structure commonly
        //     { len, array[len] }   and
        //     { selector, [select]union }
        // This routine changes references to these sorts of structure to an embedded form.
        public static void FlattenTaggedStructures()
        {
            // Build the list of tagged structures
            List <TpmStruct> taggedStructs = new List <TpmStruct>();

            foreach (TpmType tp in TpmTypes.TheTypes)
            {
                var s = tp as TpmStruct;
                if (s == null)
                {
                    continue;
                }
                var t = s;
                while (t != null && t.Fields.Count != 2)
                {
                    t = t.DerivedFrom;
                }
                if (t == null || s.SpecName.IsOneOf(DontFlatten))
                {
                    continue;
                }
                if ((t.Fields[0].MarshalType == MarshalType.ArrayCount) ||
                    (t.Fields[0].MarshalType == MarshalType.UnionSelector) ||
                    (t.Fields[0].MarshalType == MarshalType.LengthOfStruct)
                    )
                {
                    taggedStructs.Add(s);
                }
            }

            // find references to the tagged structures and replace them
            foreach (TpmType tp in TpmTypes.TheTypes)
            {
                if (!(tp is TpmStruct))
                {
                    continue;
                }
                TpmStruct t = (TpmStruct)tp;

                for (int j = 0; j < t.Fields.Count; j++)
                {
                    StructField origField = t.Fields[j];

                    if (origField.IsArray())
                    {
                        continue;   // Don't flatten arrays
                    }
                    var toEmbed = origField.Type as TpmStruct;
                    if (taggedStructs.Contains(toEmbed))
                    {
                        // If a structure to flatten is one without fields of its own,
                        // but is derived from a flattenable one, unwind the inheritance chain.
                        while (toEmbed != null && toEmbed.Fields.Count != 2)
                        {
                            toEmbed = toEmbed.DerivedFrom;
                        }

                        StructField tagToEmbed = toEmbed.Fields[0];
                        Debug.Assert(origField.MinVal == null || origField.MinVal == tagToEmbed.MinVal);
                        Debug.Assert(origField.MaxVal == null || origField.MaxVal == tagToEmbed.MaxVal);

                        var    bufToEmbed     = toEmbed.Fields[1];
                        string newTagName     = origField.Name + Helpers.Capitalize(tagToEmbed.Name);
                        string newBufTypeName = bufToEmbed.Type.SpecName;
                        var    newTagField    = new StructField(tagToEmbed, newTagName);
                        t.Fields[j] = newTagField;

                        switch (tagToEmbed.MarshalType)
                        {
                        case MarshalType.UnionSelector:
                        {
                            var newField = new UnionField(newBufTypeName, origField.Name,
                                                          origField.Comment, newTagName, t);
                            t.Fields.Insert(j + 1, newField);
                            break;
                        }

                        case MarshalType.ArrayCount:
                        {
                            var newField = new VariableLengthArray(newBufTypeName, origField.Name,
                                                                   origField.Comment, newTagName, t);
                            t.Fields.Insert(j + 1, newField);
                            break;
                        }

                        case MarshalType.LengthOfStruct:
                        {
                            var newField = new StructField(newBufTypeName, origField.Name,
                                                           origField.Comment);
                            t.Fields.Insert(j + 1, newField);
                            newTagField.MarshalType = MarshalType.LengthOfStruct;
                            newTagField.SizedField  = newField;
                            newField.MarshalType    = MarshalType.SizedStruct;
                            newField.SizeTagField   = newTagField;
                            break;
                        }

                        default:
                            throw new Exception("");
                        }
                    } // j-loop
                }
            }
        }
Esempio n. 3
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()