Ryujinx-GtkSharp/Source/Tools/GapiCodegen/UnionABIField.cs

161 lines
4.0 KiB
C#

namespace GtkSharp.Generation {
using System;
using System.Collections;
using System.IO;
using System.Xml;
using System.Collections.Generic;
public class UnionSubstruct {
List<StructABIField> fields;
XmlElement Elem;
bool is_valid;
bool unique_field;
public string abi_info_name;
public UnionSubstruct(XmlElement elem, ClassBase container_type, string abi_info_name) {
fields = new List<StructABIField> ();
Elem = elem;
is_valid = true;
unique_field = false;
if (Elem.Name == "struct") {
foreach (XmlElement child_field in elem.ChildNodes) {
if (child_field.Name != "field") {
is_valid = false;
continue;
}
fields.Add(new StructABIField (child_field, container_type, abi_info_name));
}
} else if (Elem.Name == "field") {
fields.Add(new StructABIField (Elem, container_type, abi_info_name));
unique_field = true;
}
}
public string GenerateGetSize(string indent) {
var size = indent += "new List<string>() {";
var is_first = true;
foreach (StructABIField field in fields) {
if (!is_first)
size += ",";
is_first = false;
size += "\"" + field.CName + "\"";
}
return size + "}";
}
public void EnsureParentStructName (string parent_name) {
var name = Elem.GetAttribute("name");
if (!unique_field) {
parent_name = parent_name + '.' + name;
}
StructABIField next_field = null;
foreach (var field in fields) {
field.parent_structure_name = parent_name;
}
}
public StructField Generate(GenerationInfo gen_info, string indent,
string parent_name, StructABIField prev_field,
StructABIField next, string struct_parent_name,
TextWriter tw)
{
StreamWriter sw = gen_info.Writer;
var name = Elem.GetAttribute("name");
var cname = Elem.GetAttribute("cname");
if (!unique_field) {
parent_name = parent_name + '.' + name;
}
StructABIField next_field = null;
sw.WriteLine(indent + "// union struct " + parent_name);
for(int i=0; i < fields.Count; i++) {
var field = fields[i];
next_field = fields.Count > i + 1 ? fields[i + 1] : null;
field.parent_structure_name = parent_name;
field.Generate(gen_info, indent, prev_field, next_field, struct_parent_name,
tw);
prev_field = field;
}
sw.WriteLine(indent + "// End " + parent_name);
sw.WriteLine();
return prev_field;
}
}
public class UnionABIField : StructABIField {
bool is_valid;
XmlElement Elem;
protected List<UnionSubstruct> substructs = new List<UnionSubstruct> ();
public UnionABIField (XmlElement elem, ClassBase container_type, string info_name) :
base (elem, container_type, info_name) {
Elem = elem;
is_valid = true;
foreach (XmlElement union_child in elem.ChildNodes) {
substructs.Add(new UnionSubstruct(union_child, container_type, abi_info_name));
}
}
public override StructABIField Generate (GenerationInfo gen_info, string indent,
StructABIField prev_field, StructABIField next_field, string parent_name,
TextWriter tw) {
StreamWriter sw = gen_info.Writer;
var name = Elem.GetAttribute("name");
var cname = Elem.GetAttribute("cname");
foreach (UnionSubstruct _struct in substructs)
_struct.EnsureParentStructName(cname);
foreach (UnionSubstruct _struct in substructs) {
_struct.Generate(gen_info, indent + "\t", cname, prev_field,
next_field, parent_name, tw);
}
base.Generate(gen_info, indent, prev_field, next_field, parent_name, null);
return this;
}
public override string GenerateGetSizeOf(string indent) {
string res = indent + "new List<List<string>>() { // union " + Elem.GetAttribute("cname") + "\n";
bool first = true;
indent += "\t\t\t";
foreach (UnionSubstruct _struct in substructs) {
if (!first)
res += ",\n";
first = false;
res += _struct.GenerateGetSize(indent + "\t\t\t");
}
res += "\n" + indent + "\t\t }";
return res;
}
public override bool Validate (LogWriter log)
{
if (!is_valid) {
log.Warn("Can't generate ABI compatible union");
}
return is_valid;
}
}
}