/// <summary> /// Unions in C are translated into Java classes implementing the interface that defines the union /// </summary> /// <param name="u"></param> void GenUnion(TpmUnion u) { WriteComment(u); Write($"public interface {u.Name} extends TpmUnion"); TabIn("{"); Write($"public {GetUnionSelectorType(u)} GetUnionSelector();"); TabOut("}", false); }
public void RegisterContainingUnion(TpmUnion u) { if (u.Implement && !ContainingUnions.Contains(u)) { ContainingUnions.Add(u); if (DerivedFrom != null) { DerivedFrom.RegisterContainingUnion(u); } } }
public bool IsSubsetOf(TpmUnion u) { foreach (UnionMember m in Members) { if (!u.Members.Contains(m) && !m.Type.SpecName.StartsWith("TPMS_NULL_")) { return(false); } } return(true); }
static void FixEnumTypeCollisions() { List <TpmStruct> toAdd = new List <TpmStruct>(); for (int j = 0; j < TpmTypes.TheTypes.Count; j++) { TpmType tp = TpmTypes.TheTypes[j]; if (!(tp is TpmUnion && tp.SpecName.IsOneOf(new string[] { "TPMU_PUBLIC_ID", "TPMU_SIGNATURE" }))) { continue; } // See if we have collisions. // Collided member types are converted into derived types by adding selector name to the base // type name. Struct that became a base one inherits from all the union interfaces, while // a derived struct only inherits from the base one and implements interfaces of the unions, // of which it is a member. // Base class B provides a union interface implementation only if this union contains a member // of type B. If a union U contains members of types derived from B, then B's implementation // of U's interface methods just throws NotImplementedException exception. TpmUnion u = (TpmUnion)tp; var dict = new Dictionary <string, UnionMember>(); foreach (UnionMember m in u.Members) { string typeName = m.Type.SpecName; string selectorName = m.SelectorValue.Name; if (dict.ContainsKey(typeName)) { // Collision detected. Debug.WriteLine("Collision in {0} [{1}] -- {2}", u.Name, selectorName, typeName); TpmStruct baseStruct = (TpmStruct)TpmTypes.Lookup(typeName); AddDerivedStruct(baseStruct, m, u, "Auto-derived from " + baseStruct.SpecName + " to provide unique GetUnionSelector() implementation"); if (dict[typeName] != null) { // Create the derived structure for the first occurrence. AddDerivedStruct(baseStruct, dict[typeName], u); // But do it only once... dict[typeName] = null; } } else { dict.Add(typeName, m); } } } } // FixEnumTypeCollisions()
/// <param name="selVal"> Upon return set to the value (qualified enum memeber) of the selector (or null). </param> /// <returns> Union selector type name if 's' is a member of a tagged union. Otherwise null. </returns> public static string GetUnionMemberSelectorInfo(TpmStruct s, out string selVal) { selVal = null; if (s.IsCmdStruct() || s.ContainingUnions.Count == 0) { return(null); } // If a struct is a member of multiple unions, all of them are expected to use the same selector value TpmUnion u = s.ContainingUnions.ElementAt(0); selVal = s.SpecName == TpmTypes.EmptyUnionBaseName ? TpmTypes.AlgNull : u.GetMemberOfType(s).SelectorValue.QualifiedName; return(GetUnionSelectorType(u)); }
void GenUnion(TpmUnion u) { if (!u.Implement) { return; } WriteComment(u); Write("class _DLLEXP_ " + u.Name + ": public virtual TpmUnion"); TabIn("{"); // Note: cannot sink GetUnionSelector() to the base TpmUnion interafce in C++, // as some unions use different unrelated enums as return types. Write($"public: virtual {GetUnionSelectorType(u)} GetUnionSelector() const = 0;"); Write("public: virtual TpmStructure* Clone() const { _ASSERT(FALSE); return NULL; };"); TabOut("};"); } // GenUnion()
public static void AddDerivedStruct(TpmStruct baseStruct, UnionMember curMember, TpmUnion curUnion, string comment = null) { string baseTypeName = baseStruct.SpecName; string newTypeName = baseTypeName + "_" + RemoveEnumPrefix(curMember.SelectorValue.SpecName, curMember.SelectorValue.EnclosingEnum.SpecName); if (!TpmTypes.Contains(newTypeName)) { var newStruct = new TpmStruct(newTypeName, comment ?? "Auto-derived from " + baseTypeName, baseStruct); TpmTypes.Add(newStruct); } var s = (TpmStruct)TpmTypes.Lookup(newTypeName); s.RegisterContainingUnion(curUnion); // Fix up the union field curMember.Type = s; }
/// <param name="selVal"> Upon return set to the value (qualified enum memeber) of the selector (or null). </param> /// <returns> Union selector type name if 's' is a member of a tagged union. Otherwise null. </returns> public static string GetUnionSelectorType(TpmUnion u) { return(u.Members[0].SelectorValue.EnclosingEnum.Name); }