in TssCodeGen/src/CGenJava.cs [241:451]
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()