static string GetSerOpCallExprPrefix(StructField f, string op) { string type = f.Type.StripTypedefs().Name + (f.IsArray() ? "[]" : ""); string sizeTagParams = f.SizeTagField == null ? "" : $", \"{f.SizeTagField.Name}\", \"{f.SizeTagField.Type.Name}\""; return($"buf.with(\"{f.Name}\", \"{type}\"{sizeTagParams}).{op}"); }
static string CtorParamTypeFor(StructField f) { if (f.IsArray() || !f.IsValueType()) { return($"const {f.TypeName}&"); } return(f.TypeName); }
} // TranslateConstExpr() /// <summary> Constructs language specific representation of the given TPM structure field type /// for the currently active language. In particular, applies array and byte buffer conventions. /// </summary> /// <param name="f"> Structure field metadata extracted from the TPM spec </param> /// <returns> Language specific representation of the given TPM structure field type </returns> static string TranslateFieldType(StructField f) { string typeName = f.Type.Name; if (f.IsByteBuffer()) { if (TargetLang.Cpp) { typeName = "ByteVec"; } else { if (TargetLang.Node) { return("Buffer"); } else if (TargetLang.Py) { return("bytes"); } return(typeName + "[]"); } } else if (f.IsArray()) { if (TargetLang.Cpp) { typeName = $"vector<{typeName}>"; } else { return(typeName + "[]"); } } return(typeName); }
// 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 } } }
public void Add(StructField f) { Fields.Add(f); var countTag = f.SizeTagField; if (countTag == null) { Debug.Assert(f.SizedField == null || f.IsTag() || f.Type.IsAlgOrHashAlg()); return; } Debug.Assert(countTag.MarshalType == MarshalType.LengthOfStruct ? f.MarshalType == MarshalType.Normal : f.IsArray()); // TSS implementations marshal variable length byte buffers tagged with an algorithm as fixed size arrays, // i.e. without marshaling the numeric size tag, as the algorithm tag (marshaled as a normal field) // is used to determine the buffer size. if (countTag.MarshalType == MarshalType.Normal && countTag.Type.IsAlgOrHashAlg()) { f.MarshalType = MarshalType.SpecialVariableLengthArray; } }