Fix errors again
This commit is contained in:
parent
9a2e031be2
commit
978cb5b8c8
@ -12,221 +12,5 @@ using System.Globalization;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
//From https://gitlab.com/Syroot/NintenTools.Byaml/-/blob/master/src/Syroot.NintenTools.Byaml/XmlConverter.cs
|
||||
//This allows xml to with with yamlconv and it looks better using attributes for properties
|
||||
//Todo this needs to support reference nodes
|
||||
public class XmlByamlConverter
|
||||
{
|
||||
private static readonly XNamespace _yamlconvNs = "yamlconv";
|
||||
|
||||
public static string ToXML(BymlFileData data)
|
||||
{
|
||||
XDocument doc = ToXDocument(data.RootNode, data);
|
||||
using (StringWriter writer = new StringWriter())
|
||||
{
|
||||
doc.Save(writer);
|
||||
return writer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static BymlFileData FromXML(string text) {
|
||||
return FromXDocument(XDocument.Parse(text));
|
||||
}
|
||||
|
||||
internal static BymlFileData FromXDocument(XDocument xDocument)
|
||||
{
|
||||
if (xDocument == null)
|
||||
throw new ArgumentNullException(nameof(xDocument));
|
||||
if (xDocument.Root?.Name != "yaml")
|
||||
throw new ArgumentException("Incompatible XML data. A \"yaml\" root element is required.");
|
||||
|
||||
// Retrieve information from root node.
|
||||
BymlFileData data = new BymlFileData();
|
||||
switch (xDocument.Root.Attribute(_yamlconvNs + "endianness")?.Value)
|
||||
{
|
||||
case "big": data.byteOrder = ByteOrder.BigEndian; break;
|
||||
case "little": data.byteOrder = ByteOrder.LittleEndian; break;
|
||||
default: data.byteOrder = ByteOrder.LittleEndian; break;
|
||||
}
|
||||
data.Version = UInt16.TryParse(xDocument.Root.Attribute(_yamlconvNs + "version")?.Value,
|
||||
out ushort version) ? version : (ushort)1;
|
||||
|
||||
// Generate the root node.
|
||||
data.RootNode = ReadNode(xDocument.Root);
|
||||
return data;
|
||||
}
|
||||
|
||||
private static dynamic ReadNode(XElement node)
|
||||
{
|
||||
dynamic convertValue(string value)
|
||||
{
|
||||
if (value == "null")
|
||||
return null;
|
||||
if (value == string.Empty)
|
||||
return "";
|
||||
else if (value == "true")
|
||||
return true;
|
||||
else if (value == "false")
|
||||
return false;
|
||||
else if (value.EndsWith("f"))
|
||||
return Single.Parse(value.Substring(0, value.Length - "f".Length), CultureInfo.InvariantCulture);
|
||||
else if (value.EndsWith("u"))
|
||||
return UInt32.Parse(value.Substring(0, value.Length - "u".Length), CultureInfo.InvariantCulture);
|
||||
else if (value.EndsWith("i64"))
|
||||
return Int64.Parse(value.Substring(0, value.Length - "i64".Length), CultureInfo.InvariantCulture);
|
||||
else if (value.EndsWith("u64"))
|
||||
return UInt64.Parse(value.Substring(0, value.Length - "u64".Length), CultureInfo.InvariantCulture);
|
||||
else if (value.EndsWith("d"))
|
||||
return Double.Parse(value.Substring(0, value.Length - "d".Length), CultureInfo.InvariantCulture);
|
||||
else
|
||||
return Int32.Parse(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
string convertString() => node.Value.ToString();
|
||||
|
||||
List<ByamlPathPoint> convertPath()
|
||||
{
|
||||
List<ByamlPathPoint> path = new List<ByamlPathPoint>();
|
||||
foreach (XElement pathPoint in node.Elements("point"))
|
||||
path.Add(convertPathPoint(pathPoint));
|
||||
return path;
|
||||
}
|
||||
|
||||
ByamlPathPoint convertPathPoint(XElement pathPoint)
|
||||
{
|
||||
return new ByamlPathPoint
|
||||
{
|
||||
Position = new Vector3F(
|
||||
convertValue(pathPoint.Attribute("x")?.Value ?? "0f"),
|
||||
convertValue(pathPoint.Attribute("y")?.Value ?? "0f"),
|
||||
convertValue(pathPoint.Attribute("z")?.Value ?? "0f")),
|
||||
Normal = new Vector3F(
|
||||
convertValue(pathPoint.Attribute("nx")?.Value ?? "0f"),
|
||||
convertValue(pathPoint.Attribute("ny")?.Value ?? "0f"),
|
||||
convertValue(pathPoint.Attribute("nz")?.Value ?? "0f")),
|
||||
Unknown = convertValue(pathPoint.Attribute("val")?.Value ?? "0")
|
||||
};
|
||||
}
|
||||
|
||||
Dictionary<string, dynamic> convertDictionary()
|
||||
{
|
||||
Dictionary<string, dynamic> dictionary = new Dictionary<string, dynamic>();
|
||||
foreach (XElement element in node.Elements())
|
||||
dictionary.Add(XmlConvert.DecodeName(element.Name.ToString()), ReadNode(element));
|
||||
// Only keep non-namespaced attributes for now to filter out yamlconv and xml(ns) ones.
|
||||
foreach (XAttribute attribute in node.Attributes().Where(x => x.Name.Namespace == XNamespace.None))
|
||||
dictionary.Add(XmlConvert.DecodeName(attribute.Name.ToString()), convertValue(attribute.Value));
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
List<dynamic> convertArray()
|
||||
{
|
||||
List<dynamic> array = new List<dynamic>();
|
||||
foreach (XElement element in node.Elements("value"))
|
||||
array.Add(ReadNode(element));
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
// Detecting the special "type" attribute like this is unsafe as it could also be a dictionary with a "type"
|
||||
// key. Yamlconv should have namespaced its attribute to safely identify it.
|
||||
switch (node.Attributes("type").SingleOrDefault()?.Value)
|
||||
{
|
||||
// TODO: Add null support. Can null be set for value types?
|
||||
// TODO: Add reference support. Use Element with encoded XPath.
|
||||
case null when node.HasAttributes || node.HasElements: return convertDictionary();
|
||||
case null: return convertValue(node.Value);
|
||||
case "array": return convertArray();
|
||||
case "path": return convertPath();
|
||||
case "string": return convertString();
|
||||
default: throw new ByamlException("Unknown XML contents.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static XDocument ToXDocument(dynamic root, BymlFileData data)
|
||||
{
|
||||
XElement rootNode = SaveNode("yaml", root, false);
|
||||
|
||||
List<XAttribute> attribs = rootNode.Attributes().ToList();
|
||||
attribs.Insert(0, new XAttribute(XNamespace.Xmlns + "yamlconv", "yamlconv"));
|
||||
attribs.Insert(1, new XAttribute(_yamlconvNs + "endianness",
|
||||
data.byteOrder == ByteOrder.LittleEndian ? "little" : "big"));
|
||||
attribs.Insert(2, new XAttribute(_yamlconvNs + "offsetCount", data.SupportPaths ? 4 : 3));
|
||||
attribs.Insert(3, new XAttribute(_yamlconvNs + "byamlVersion", data.Version));
|
||||
rootNode.Attributes().Remove();
|
||||
rootNode.Add(attribs);
|
||||
|
||||
return new XDocument(new XDeclaration("1.0", "utf-8", null), rootNode);
|
||||
}
|
||||
|
||||
private static XObject SaveNode(string name, dynamic node, bool isArrayElement)
|
||||
{
|
||||
XObject convertValue(object value)
|
||||
=> isArrayElement ? new XElement(name, value) : (XObject)new XAttribute(name, value);
|
||||
|
||||
XElement convertString(string stringNode)
|
||||
=> new XElement(name, new XAttribute("type", "string"), stringNode);
|
||||
|
||||
XElement convertPathPoint(ByamlPathPoint pathPointNode)
|
||||
{
|
||||
return new XElement("point",
|
||||
new XAttribute("x", getSingleString(pathPointNode.Position.X)),
|
||||
new XAttribute("y", getSingleString(pathPointNode.Position.Y)),
|
||||
new XAttribute("z", getSingleString(pathPointNode.Position.Z)),
|
||||
new XAttribute("nx", getSingleString(pathPointNode.Normal.X)),
|
||||
new XAttribute("ny", getSingleString(pathPointNode.Normal.Y)),
|
||||
new XAttribute("nz", getSingleString(pathPointNode.Normal.Z)),
|
||||
new XAttribute("val", getUInt32String(pathPointNode.Unknown)));
|
||||
}
|
||||
|
||||
XObject convertPath(List<ByamlPathPoint> pathNode)
|
||||
{
|
||||
XElement xElement = new XElement(name, new XAttribute("type", "path"));
|
||||
foreach (dynamic element in pathNode)
|
||||
xElement.Add(SaveNode("point", element, true));
|
||||
return xElement;
|
||||
}
|
||||
|
||||
XElement convertDictionary(IDictionary<string, dynamic> dictionaryNode)
|
||||
{
|
||||
XElement xElement = new XElement(name);
|
||||
foreach (KeyValuePair<string, dynamic> element in dictionaryNode.OrderBy(x => x.Key, StringComparer.Ordinal))
|
||||
xElement.Add(SaveNode(element.Key, element.Value, false));
|
||||
return xElement;
|
||||
}
|
||||
|
||||
XElement convertArray(IEnumerable<dynamic> arrayNode)
|
||||
{
|
||||
XElement xElement = new XElement(name, new XAttribute("type", "array"));
|
||||
foreach (dynamic element in arrayNode)
|
||||
xElement.Add(SaveNode("value", element, true));
|
||||
return xElement;
|
||||
}
|
||||
|
||||
string getBooleanString(Boolean value) => value ? "true" : "false";
|
||||
string getInt32String(Int32 value) => value.ToString(CultureInfo.InvariantCulture);
|
||||
string getSingleString(Single value) => value.ToString(CultureInfo.InvariantCulture) + "f";
|
||||
string getUInt32String(UInt32 value) => value.ToString(CultureInfo.InvariantCulture) + "u";
|
||||
string getInt64String(Int64 value) => value.ToString(CultureInfo.InvariantCulture) + "i64";
|
||||
string getUInt64String(UInt64 value) => value.ToString(CultureInfo.InvariantCulture) + "u64";
|
||||
string getDoubleString(Double value) => value.ToString(CultureInfo.InvariantCulture) + "d";
|
||||
|
||||
if (node == null) return convertString("null");
|
||||
|
||||
name = XmlConvert.EncodeName(name);
|
||||
if (node is bool) return convertValue(getBooleanString((bool)node));
|
||||
else if (node is int) return convertValue(getInt32String((int)node));
|
||||
else if (node is uint) return convertValue(getUInt32String((uint)node));
|
||||
else if (node is float) return convertValue(getSingleString((float)node));
|
||||
else if (node is UInt64) return convertValue(getUInt64String((UInt64)node));
|
||||
else if (node is Int64) return convertValue(getInt64String((Int64)node));
|
||||
else if (node is Double) return convertValue(getDoubleString((Double)node));
|
||||
else if (node is string) return convertString(node);
|
||||
else if (node is ByamlPathPoint) return convertPathPoint((ByamlPathPoint)node);
|
||||
else if (node is List<ByamlPathPoint>) return convertPath((List<ByamlPathPoint>)node);
|
||||
else if (node is IDictionary<string, dynamic>) return convertDictionary(node);
|
||||
else if (node is IEnumerable<dynamic>) return convertArray(node);
|
||||
else throw new Exception("Unsupported node type! " + node.GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user