mirror of
https://github.com/Ryujinx/GtkSharp.git
synced 2024-12-23 10:45:30 +00:00
161 lines
4 KiB
C#
161 lines
4 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;
|
|
}
|
|
}
|
|
}
|