protected ClassBase(XmlElement namespaceElement, XmlElement element) : base(namespaceElement, element) { IsDeprecated = element.GetAttributeAsBoolean(Constants.Deprecated); IsAbstract = element.GetAttributeAsBoolean(Constants.Abstract); IsAbiFieldsValid = true; var parentType = Element.GetAttribute(Constants.Parent); var abiFieldsCount = 0; foreach (XmlNode node in element.ChildNodes) { if (!(node is XmlElement)) { continue; } var member = (XmlElement)node; StructAbiField abiField = null; switch (member.Name) { // Make sure ABI fields are taken into account, even when hidden. case Constants.Field: { abiFieldsCount += 1; // Skip instance parent struct if present, taking into account // bindinator broken behaviour concerning parent field (ie. // marking it as pointer, somehow risky but good enough for now.) if (abiFieldsCount != 1 || parentType == "" || member.GetAttribute(Constants.Type).Replace("*", "") != parentType) { abiField = new StructAbiField(member, this, "abi_info"); AbiFields.Add(abiField); } break; } case "union": abiField = new UnionAbiField(member, this, "abi_info"); AbiFields.Add(abiField); break; } if (member.GetAttributeAsBoolean(Constants.Hidden)) { continue; } string name; switch (member.Name) { case Constants.Method: name = member.GetAttribute(Constants.Name); while (Methods.ContainsKey(name)) { name += "mangled"; } Methods.Add(name, new Method(member, this)); break; case Constants.Property: name = member.GetAttribute(Constants.Name); while (Properties.ContainsKey(name)) { name += "mangled"; } Properties.Add(name, new Property(member, this)); break; case Constants.Field: //TODO: Generate callbacks. if (member.GetAttributeAsBoolean("is_callback")) { continue; } name = member.GetAttribute(Constants.Name); while (_fields.ContainsKey(name)) { name += "mangled"; } var field = new ObjectField(member, this); field.AbiField = abiField; _fields.Add(name, field); break; case Constants.Implements: ParseImplements(member); break; case Constants.Constructor: Constructors.Add(new Ctor(member, this)); break; case "constant": name = member.GetAttribute(Constants.Name); _constants.Add(name, new Constant(member)); break; } } }
protected void GenerateStructAbi(GenerationInfo generationInfo, IList <StructAbiField> fields, string infoName, string structName) { if (fields == null) { fields = AbiFields; } var logWriter = new LogWriter(QualifiedName); if (!CheckStructAbiParent(logWriter, out var csParentStruct)) { return; } var streamWriter = generationInfo.Writer; streamWriter.WriteLine(); streamWriter.WriteLine("\t\t// Internal representation of the wrapped structure ABI."); streamWriter.WriteLine($"\t\tstatic GLib.AbiStruct _{infoName} = null;"); streamWriter.WriteLine( $"\t\tstatic public {(!string.IsNullOrEmpty(csParentStruct) ? "new " : "")}GLib.AbiStruct {infoName} {{"); streamWriter.WriteLine("\t\t\tget {"); streamWriter.WriteLine($"\t\t\t\tif (_{infoName} == null)"); // Generate Tests var usingParentFields = false; if (fields.Count > 0) { streamWriter.WriteLine($"\t\t\t\t\t_{infoName} = new GLib.AbiStruct (new List<GLib.AbiField>{{ "); if (generationInfo.CAbiWriter != null) { generationInfo.CAbiWriter.WriteLine( "\tg_print(\"\\\"sizeof({0})\\\": \\\"%\" G_GUINT64_FORMAT \"\\\"\\n\", (guint64) sizeof({0}));", structName); generationInfo.AbiWriter.WriteLine( "\t\t\tConsole.WriteLine(\"\\\"sizeof({0})\\\": \\\"\" + {1}.{2}.{3}.Size + \"\\\"\");", structName, Namespace, Name, infoName); } } else { if (!string.IsNullOrEmpty(csParentStruct)) { streamWriter.WriteLine("\t\t\t\t\t_{1} = new GLib.AbiStruct ({0}.{1}.Fields);", csParentStruct, infoName); usingParentFields = true; } else { streamWriter.WriteLine("\t\t\t\t\t_{0} = new GLib.AbiStruct (new List<GLib.AbiField>{{ ", infoName); } } StructAbiField previous = null; var fieldAlignmentStructuresWriter = new StringWriter(); for (var i = 0; i < fields.Count; i++) { var field = fields[i]; var next = fields.Count > i + 1 ? fields[i + 1] : null; previous = field.Generate(generationInfo, "\t\t\t\t\t", previous, next, csParentStruct, fieldAlignmentStructuresWriter); if (field is UnionAbiField || generationInfo.CAbiWriter == null || field.IsBitfield) { continue; } generationInfo.CAbiWriter.WriteLine( "\tg_print(\"\\\"{0}.{1}\\\": \\\"%\" G_GUINT64_FORMAT \"\\\"\\n\", (guint64) G_STRUCT_OFFSET({0}, {1}));", structName, field.CName); generationInfo.AbiWriter.WriteLine( "\t\t\tConsole.WriteLine(\"\\\"{0}.{3}\\\": \\\"\" + {1}.{2}.{4}.GetFieldOffset(\"{3}\") + \"\\\"\");", structName, Namespace, Name, field.CName, infoName); } if (fields.Count > 0 && generationInfo.CAbiWriter != null) { generationInfo.AbiWriter.Flush(); generationInfo.CAbiWriter.Flush(); } if (!usingParentFields) { streamWriter.WriteLine("\t\t\t\t\t});"); } streamWriter.WriteLine(); streamWriter.WriteLine($"\t\t\t\treturn _{infoName};"); streamWriter.WriteLine("\t\t\t}"); streamWriter.WriteLine("\t\t}"); streamWriter.WriteLine(); streamWriter.WriteLine(fieldAlignmentStructuresWriter.ToString()); streamWriter.WriteLine("\t\t// End of the ABI representation."); streamWriter.WriteLine(); }