Ryujinx-GtkSharp/Source/Tools/GapiCodegen/StructABIField.cs
2021-08-15 20:27:58 +06:00

145 lines
4.0 KiB
C#

namespace GtkSharp.Generation {
using System;
using System.Collections;
using System.IO;
using System.Xml;
public class StructABIField : StructField {
protected new ClassBase container_type;
public string parent_structure_name;
public string abi_info_name;
public StructABIField (XmlElement elem, ClassBase container_type,
string info_name) : base (elem, container_type) {
this.container_type = container_type;
this.getOffsetName = null;
this.abi_info_name = info_name;
}
public override string CName {
get {
if (parent_structure_name != null)
return parent_structure_name + '.' + elem.GetAttribute ("cname");
return elem.GetAttribute ("cname");
}
}
public override void Generate (GenerationInfo gen_info, string indent) {
base.Generate(gen_info, indent);
}
// All field are visible and private
// as the goal is to respect the ABI
protected override string Access {
get {
return "private";
}
}
public override bool Hidden {
get {
return false;
}
}
public override bool Validate (LogWriter log)
{
string cstype = SymbolTable.Table.GetCSType(CType, true);
if (elem.GetAttributeAsBoolean("is_callback"))
return true;
if (cstype == null || cstype == "") {
log.Warn (" field \"" + CName + "\" has no cstype, can't generate ABI field.");
return false;
}
if (!base.Validate (log))
return false;
return true;
}
public void SetGetOffseName() {
this.getOffsetName = "Get" + CName + "Offset";
}
public override string GenerateGetSizeOf(string indent) {
return base.GenerateGetSizeOf(indent) + " // " + CName;
}
public virtual StructABIField Generate (GenerationInfo gen_info, string indent,
StructABIField prev_field, StructABIField next_field, string parent_name,
TextWriter structw) {
StreamWriter sw = gen_info.Writer;
IGeneratable gen = SymbolTable.Table[CType];
sw.WriteLine("{0}\tnew GLib.AbiField(\"{1}\"", indent, CName);
indent = indent + "\t\t";
if (prev_field != null) {
sw.WriteLine(indent + ", -1");
} else {
if (parent_name != "")
sw.WriteLine(indent + ", " + parent_name + "." + abi_info_name + ".Fields");
else
sw.WriteLine(indent + ", 0");
}
sw.WriteLine(indent + ", " + GenerateGetSizeOf(""));
var prev_field_name = prev_field != null ? "\"" + prev_field.CName + "\"" : "null";
sw.WriteLine(indent + ", " + prev_field_name);
var container_name = container_type.CName.Replace(".", "_");
var sanitized_name = CName.Replace(".", "_");
var alig_struct_name = container_name + "_" + sanitized_name + "Align";
var next_field_name = next_field != null ? "\"" + next_field.CName + "\"" : "null";
sw.WriteLine(indent + ", " + next_field_name);
if (structw != null) {
string min_align = gen != null ? gen.GenerateAlign() : null;
// Do not generate structs if the type is a simple pointer.
if (IsCPointer())
min_align = "(uint) sizeof(IntPtr)";
if (IsBitfield)
min_align = "1";
if (min_align == null) {
var tmpindent = "\t\t";
structw.WriteLine(tmpindent + "[StructLayout(LayoutKind.Sequential)]");
structw.WriteLine(tmpindent + "public struct " + alig_struct_name);
structw.WriteLine(tmpindent + "{");
structw.WriteLine(tmpindent + "\tsbyte f1;");
base.Generate(gen_info, tmpindent + "\t", true, structw);
structw.WriteLine(tmpindent + "}");
structw.WriteLine();
var fieldname = SymbolTable.Table.MangleName (CName).Replace(".", "_");
if (IsArray && IsNullTermArray)
fieldname += "Ptr";
sw.WriteLine(indent + ", (long) Marshal.OffsetOf<" + alig_struct_name + ">(\"" + fieldname + "\")");
} else {
sw.WriteLine(indent + ", " + min_align);
}
}
gen_info.Writer = sw;
uint bits = 0;
var bitsstr = elem.GetAttribute("bits");
if (bitsstr != null && bitsstr != "")
bits = (uint) Int32.Parse(bitsstr);
sw.WriteLine(indent + ", " + bits);
sw.WriteLine(indent + "),");
return this;
}
}
}