void WriteConstraints(StructField f) { if (f.Domain.Count == 0) { return; } string constraint = ""; if (f.Domain.Count > 1) { // Here we only expect multiple SingleValue constraints. foreach (var val in f.Domain) { AddConstraint(ref constraint, null, (val as SingleValue).Value); } constraint = "Values = new[] {" + constraint + "}"; } else { AddConstraint(ref constraint, "MinVal", f.Domain[0, Constraint.Type.Min]); AddConstraint(ref constraint, "MaxVal", f.Domain[0, Constraint.Type.Max]); AddConstraint(ref constraint, "OnlyVal", f.Domain[0, Constraint.Type.Single]); Debug.Assert(constraint != ""); } Write($"[Range({constraint})]"); }
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 TransType(StructField f) { if (f.MarshalType == MarshalType.UnionObject) { return($"shared_ptr<{f.TypeName}>"); } return(f.TypeName); }
static string CtorParamTypeFor(StructField f) { if (f.IsArray() || !f.IsValueType()) { return($"const {f.TypeName}&"); } return(f.TypeName); }
public string StructFieldToMemberString(StructField field) { if (field.Type.TypeType == FieldType.BaseType || field.Type.TypeType == FieldType.Enum) { return(string.Format("public {0} {1};", BaseTypeTran(field.Type.Type.Value), field.Name.Value)); } string typeString = TypeToString(field.Type); return(string.Format("public {0} {1} = new {0}();", typeString, field.Name.Value)); }
private static StringBuilder AppendField(this StringBuilder sb, StructField field) { sb.Append("public "); sb.AppendFieldTypeString(field); sb.Append(' ').Append(field.Name.Value); if (field.Type.TypeType > FieldType.Enum) { sb.Append(" = new ").AppendFieldTypeString(field).Append("()"); } sb.Append(';'); return(sb); }
public static string GetParamComment(StructField f, string prefix = "", string indent = " ") { string beg = TargetLang.DotNet || TargetLang.Cpp ? "<param name = \"" : TargetLang.Java || TargetLang.Node ? "@param " : ""; string med = TargetLang.DotNet || TargetLang.Cpp ? "\"> " : TargetLang.Java || TargetLang.Node ? " " : ": "; string end = TargetLang.DotNet || TargetLang.Cpp ? " </param>" : TargetLang.Java || TargetLang.Node ? "" : ""; string unionList = GetUnionChoicesList(f.Type); string comment = f.Comment + (unionList == "" ? "" : eol + unionList); string fieldType = TargetLang.Py ? $" ({f.TypeName})" : ""; return(Helpers.WrapText(beg + prefix + f.Name + fieldType + med + MandatoryComment(comment) + end, indent)); }
void GenCommand(TpmStruct req, CommandFlavor gen) { var resp = GetRespStruct(req); string cmdName = GetCommandName(req); if (gen == CommandFlavor.AsyncResponse) { cmdName += "Complete"; } string annotation = Helpers.WrapText(AsSummary(req.Comment)) + eol; var reqFields = new StructField[0]; if (gen != CommandFlavor.AsyncResponse) { reqFields = req.NonTagFields; foreach (var f in reqFields) { annotation += GetParamComment(f) + eol; } } WriteComment(annotation + (GetReturnComment(resp.NonTagFields)), false); string returnType = GetCommandReturnType(gen, resp, cmdName, out string returnFieldName); if (reqFields.Length > 1) { Write(returnType + " " + cmdName); TabIn("("); if (gen != CommandFlavor.AsyncResponse) { foreach (var f in reqFields) { Write(CtorParamTypeFor(f) + " " + f.Name + Separator(f, reqFields, ", ")); } } TabOut(");"); Write(""); } else { string param = reqFields.Length == 1 ? CtorParamTypeFor(reqFields[0]) + " " + reqFields[0].Name : ""; Write($"{returnType} {cmdName}({param});"); } } // GenCommand()
private static StringBuilder AppendFieldTypeString(this StringBuilder sb, StructField field) { sb.Append(ToTypeNameString(field.Type)); if (field.Type.TypeType == FieldType.Vector) { sb.Append('<'); sb.Append(ToExternTypeString(field.Type.ExternTypes[0])); sb.Append('>'); } else if (field.Type.TypeType == FieldType.Map) { sb.Append('<'); sb.Append(ToExternTypeString(field.Type.ExternTypes[0])); sb.Append(','); sb.Append(ToExternTypeString(field.Type.ExternTypes[1])); sb.Append('>'); } return(sb); }
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; } }
private static StringBuilder AppendField(this StringBuilder sb, StructField field) { sb.Append("public "); sb.AppendFieldTypeString(field); sb.Append(' ').Append(field.Name.Value); if (field.Type.TypeType == FieldType.BaseType) { if (field.Type.Type.Value != "string" && field.Type.Type.Value != "bytes") { if (field.Type.Type.Value == "bool") { sb.Append(" = false"); } else { sb.Append(" = 0"); } } } sb.Append(';'); return(sb); }
} // 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); }
protected string NsQualifiedType(StructField f, string nameSpace) { return((f.Type.IsElementary() ? "" : nameSpace) + f.TypeName); }
void GenHandleTable() { Write("//-----------------------------------------------------------------------------"); Write("//------------------------- COMMAND INFO -----------------------------------"); Write("//-----------------------------------------------------------------------------"); Write("public static class CommandInformation"); TabIn("{"); Write("public static CommandInfo[] Info = new CommandInfo[]"); TabIn("{"); bool printComma = false; foreach (var req in TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest())) { TpmStruct resp = GetRespStruct(req); string cmdName = GetCommandName(req); string transCmdName = TargetLang.TypeToDotNet(cmdName); string reqStructName = "Tpm2" + transCmdName + "Request"; // encryptable parms? ParmCryptInfo cryptInfo = 0; if (req.Fields.Count > req.NumHandles) { // find the first field that is not a handle StructField parm0 = req.Fields[req.NumHandles]; if (parm0.MarshalType.IsOneOf(MarshalType.LengthOfStruct, MarshalType.ArrayCount)) { string typeName = parm0.Type.StripTypedefs().Name; if (typeName == "uint") { cryptInfo |= ParmCryptInfo.EncIn4; } else if (typeName == "ushort") { cryptInfo |= ParmCryptInfo.Enc2In2; } } } if (resp.Fields.Count > resp.NumHandles) { // find the first field that is not a handle StructField parm0 = resp.Fields[resp.NumHandles]; if (parm0.MarshalType.IsOneOf(MarshalType.LengthOfStruct, MarshalType.ArrayCount)) { string typeName = parm0.Type.StripTypedefs().Name; if (typeName == "uint") { cryptInfo |= ParmCryptInfo.DecOut4; } else if (typeName == "ushort") { cryptInfo |= ParmCryptInfo.DecOut2; } } } string handleTypeNames = ""; // types of input handles if (req.NumHandles > 0) { for (int j = 0; j < req.NumHandles; j++) { StructField hField = req.Fields[j]; string origHandleType = hField.Type.SpecName; handleTypeNames += origHandleType + " "; TpmType tpx = TpmTypes.Lookup(origHandleType); } } handleTypeNames = handleTypeNames.TrimEnd(new char[] { ' ' }); handleTypeNames = "\"" + handleTypeNames + "\""; string respTypeId = !resp.Implement ? "EmptyResponse" : resp.Name; WriteComma(ref printComma); Write($"new CommandInfo(TpmCc.{transCmdName}, {req.NumHandles}, {resp.NumHandles}, {req.NumAuthHandles}, " + $"typeof({reqStructName}), typeof({respTypeId}), {(uint)cryptInfo}, {handleTypeNames})", false); } TabOut("};"); TabOut("}"); }
} // GenCommandDispatchers() void GenCommandDispatcher(TpmStruct req, CommandFlavor gen) { var resp = GetRespStruct(req); string cmdName = GetCommandName(req); string cmdCode = "TPM_CC::" + cmdName; string inStructId = req.Name + "_ID"; string outStructId = resp.Name + "_ID"; switch (gen) { case CommandFlavor.AsyncCommand: cmdName += ""; break; case CommandFlavor.AsyncResponse: cmdName += "Complete"; break; default: break; } string returnFieldName; string returnType = GetCommandReturnType(gen, resp, cmdName, out returnFieldName); string className = " Tpm2::" + (gen != CommandFlavor.Synch ? "AsyncMethods::" : ""); bool paramsPresent = gen != CommandFlavor.AsyncResponse; var cmdParamFields = paramsPresent ? req.NonTagFields : new StructField[0]; bool multiline = cmdParamFields.Count() > 1; StructField lastParm = cmdParamFields.Count() > 0 ? lastParm = cmdParamFields.Last() : null; Write(returnType + className + cmdName + "(" + (cmdParamFields.Count() == 0 ? ")" : (multiline ? "" : CtorParamTypeFor(cmdParamFields[0]) + " " + cmdParamFields[0].Name + ")"))); if (multiline) { TabIn(); foreach (var f in cmdParamFields) { Write(CtorParamTypeFor(f) + " " + f.Name + (f == lastParm ? ")" : ", ")); } TabOut(); } TabIn("{"); string reqParams = ""; if (paramsPresent && req.Fields.Count() != 0) { string ctorInitList = string.Join(", ", cmdParamFields.Select(f => f.Name)); Write($"{req.Name} req({ctorInitList});"); reqParams = ", req"; } string respParam = ""; if (returnType != "void") { Debug.Assert(resp.Fields.Count() != 0); Write($"{resp.Name} resp;"); respParam = ", resp"; } string dispatchCall = gen == CommandFlavor.AsyncCommand ? "theTpm.DispatchOut" : gen == CommandFlavor.AsyncResponse ? "theTpm.DispatchIn" : "Dispatch"; Write(dispatchCall + $"({cmdCode}{reqParams}{respParam});"); if (gen != CommandFlavor.AsyncCommand) { if (returnFieldName != null) { Write($"return resp.{returnFieldName};"); } else if (returnType != "void") { Write("return resp;"); } } TabOut("}"); } // GenCommandDispatcher()
// 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 } } }
internal static string ConstTag(StructField f) { string rawName = f.Domain[0, Constraint.Type.Single].Expr; return(TpmTypes.LookupConstant(rawName).QualifiedName); }
void WriteFieldDef(StructField f, string initializerOrBody = ";") { Write("[DataMember()]"); Write($"public {f.TypeName} {f.Name}{initializerOrBody}"); }