} // GetToTpmFieldsMarshalOps() public static List <string> GetFromTpmFieldsMarshalOps(StructField[] fields) { var marshalOps = new List <string>(); foreach (StructField f in fields) { int size = f.Type.GetSize(); string fieldName = ThisMember + f.Name; switch (f.MarshalType) { case MarshalType.Normal: if (f.IsValueType()) { marshalOps.Add($"{fieldName} = buf.read{WireNameForInt(size)}()"); } else { marshalOps.Add(TargetLang.Cpp ? $"{fieldName}.initFromTpm(buf)" : $"{fieldName} = {f.TypeName}.fromTpm(buf)"); } if (f.Attrs.HasFlag(StructFieldAttr.TermOnNull)) { marshalOps.Add(TargetLang.If($"{fieldName} == {TpmTypes.AlgNull}") + " return"); } break; case MarshalType.ConstantValue: // TODO: Add assertion by comparing with the expected constant marshalOps.Add($"buf.read{WireNameForInt(size)}()"); break; case MarshalType.SizedStruct: Debug.Assert(f.SizeTagField != null); marshalOps.Add(TargetLang.Cpp ? $"buf.readSizedObj({fieldName})" : $"{fieldName} = buf.createSizedObj({TargetLang.TypeInfo(f.TypeName)})"); break; case MarshalType.EncryptedVariableLengthArray: marshalOps.Add($"{fieldName} = buf.readByteBuf(buf.getCurStuctRemainingSize())"); break; case MarshalType.SpecialVariableLengthArray: // TPMT_HA size is inferred from the hash algorithm Debug.Assert(f.IsByteBuffer() && f.SizeTagField.Type.GetSize() == 2); marshalOps.Add($"{fieldName} = buf.readByteBuf({TargetLang.DigestSize(f.SizeTagField.Name)})"); break; case MarshalType.VariableLengthArray: var sizeTagLen = f.SizeTagField.Type.GetSize(); if (f.IsByteBuffer()) { marshalOps.Add($"{fieldName} = buf.readSizedByteBuf(" + (sizeTagLen == 2 ? ")" : $"{sizeTagLen})")); } else if (f.IsValueType()) { marshalOps.Add(TargetLang.Cpp ? $"buf.readValArr({fieldName}, {f.Type.GetSize()})" : $"{fieldName} = buf.readValArr({f.Type.GetSize()})"); } else { marshalOps.Add(TargetLang.Cpp ? $"buf.readObjArr({fieldName})" : $"{fieldName} = buf.readObjArr({TargetLang.TypeInfo(f.TypeName.TrimEnd('[', ']'))})"); } break; case MarshalType.UnionSelector: var localVar = TargetLang.LocalVar(f.Name, f.TypeName); marshalOps.Add($"{localVar} = " + (f.IsValueType() ? $"buf.read{WireNameForInt(size)}()" : $"{f.TypeName}.fromTpm(buf)")); break; case MarshalType.UnionObject: var selector = (f as UnionField).UnionSelector.Name; marshalOps.Add(TargetLang.Cpp ? $"UnionFactory::Create({fieldName}, {selector})" : $"{fieldName} = UnionFactory.create({TargetLang.Quote(f.TypeName)}, {selector})"); marshalOps.Add($"{fieldName}{TargetLang.Member}initFromTpm(buf)"); break; default: break; } } return(marshalOps); } // GetFromTpmFieldsMarshalOps()
public static List <string> GetToTpmFieldsMarshalOps(StructField[] fields) { var marshalOps = new List <string>(); foreach (StructField f in fields) { int size = f.Type.GetSize(); string fieldName = ThisMember + f.Name; switch (f.MarshalType) { case MarshalType.Normal: if (f.IsValueType()) { marshalOps.Add($"buf.write{WireNameForInt(size)}({fieldName})"); } else { marshalOps.Add($"{fieldName}.toTpm(buf)"); } if (f.Attrs.HasFlag(StructFieldAttr.TermOnNull)) { marshalOps.Add(TargetLang.If($"{fieldName} == {TpmTypes.AlgNull}") + " return"); } break; case MarshalType.ConstantValue: marshalOps.Add($"buf.write{WireNameForInt(size)}({ConstTag(f)})"); break; case MarshalType.SizedStruct: Debug.Assert(f.SizeTagField != null); marshalOps.Add($"buf.writeSizedObj({fieldName})"); break; case MarshalType.EncryptedVariableLengthArray: case MarshalType.SpecialVariableLengthArray: // TPMT_HA size is tagged by its hash alg (the first field) marshalOps.Add($"buf.writeByteBuf({fieldName})"); break; case MarshalType.VariableLengthArray: var sizeTagLen = f.SizeTagField.Type.GetSize(); if (f.IsByteBuffer()) { marshalOps.Add($"buf.writeSizedByteBuf({fieldName}" + (sizeTagLen == 2 ? ")" : $", {sizeTagLen})")); } else if (f.IsValueType()) { marshalOps.Add($"buf.writeValArr({fieldName}, {size})"); } else { marshalOps.Add($"buf.writeObjArr({fieldName})"); } break; case MarshalType.UnionSelector: // A trick to allow using default-constructed TPMT_SENSITIVE as an empty (non-marshaling) object string unionField = ThisMember + f.RelatedUnion.Name; if (f == fields.First()) { marshalOps.Add(TargetLang.If($"{unionField} == {TargetLang.Null}") + " return"); } marshalOps.Add($"buf.write{WireNameForInt(size)}({unionField}{TargetLang.Member}GetUnionSelector())"); break; case MarshalType.UnionObject: marshalOps.Add($"{fieldName}{TargetLang.Member}toTpm(buf)"); break; default: Debug.Assert(false); break; } } return(marshalOps); } // GetToTpmFieldsMarshalOps()