mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Fix loading of binary and canonical constants
This commit is contained in:
@@ -282,52 +282,64 @@ internal class AsmMarkupLoader
|
|||||||
foreach (var constant in Program.Body.OfType<ConstantDirective>())
|
foreach (var constant in Program.Body.OfType<ConstantDirective>())
|
||||||
{
|
{
|
||||||
object constantValue, persistData = null;
|
object constantValue, persistData = null;
|
||||||
|
MarkupConstantPersistMode mode;
|
||||||
|
|
||||||
var constantTypeSchema = ResolveTypeFromQualifiedName(constant.TypeName);
|
var constantTypeSchema = ResolveTypeFromQualifiedName(constant.TypeName);
|
||||||
|
|
||||||
if (constant is StringEncodedConstantDirective encodedConstant)
|
if (constant is StringEncodedConstantDirective stringEncodedConstant)
|
||||||
{
|
{
|
||||||
var parseResult = constantTypeSchema.TypeConverter(encodedConstant.Content, stringTypeSchema, out constantValue);
|
var stringParseResult = constantTypeSchema.TypeConverter(stringEncodedConstant.Content, stringTypeSchema, out constantValue);
|
||||||
if (parseResult.Failed)
|
if (stringParseResult.Failed)
|
||||||
{
|
{
|
||||||
ReportError($"Failed to create an instance of '{constant.TypeName}' from '{encodedConstant.Content}'", constant);
|
ReportError($"Failed to create an instance of '{constant.TypeName}' from '{stringEncodedConstant.Content}'", constant);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
persistData = encodedConstant.Content;
|
persistData = stringEncodedConstant.Content;
|
||||||
|
mode = MarkupConstantPersistMode.FromString;
|
||||||
}
|
}
|
||||||
else
|
else if (constant is CanonicalInstanceConstantDirective canonicalInstanceConstant)
|
||||||
{
|
{
|
||||||
var xmlElem = System.Xml.Linq.XElement.Parse(constant.Constructor);
|
var canonicalName = canonicalInstanceConstant.CanonicalName;
|
||||||
|
|
||||||
|
persistData = canonicalName;
|
||||||
|
mode = MarkupConstantPersistMode.Canonical;
|
||||||
|
|
||||||
constantValue = constantTypeSchema.ConstructDefault();
|
constantValue = constantTypeSchema.FindCanonicalInstance(canonicalName);
|
||||||
|
|
||||||
foreach (var attr in xmlElem.Attributes())
|
if (constantValue is null)
|
||||||
{
|
{
|
||||||
var propName = attr.Name.LocalName;
|
var canonicalParseResult = constantTypeSchema.TypeConverter(canonicalName, stringTypeSchema, out constantValue);
|
||||||
var prop = constantTypeSchema.FindProperty(propName);
|
if (canonicalParseResult.Failed)
|
||||||
|
|
||||||
var propConvertResult = prop.PropertyType.TypeConverter(attr.Value, stringTypeSchema, out var propValue);
|
|
||||||
if (propConvertResult.Failed)
|
|
||||||
{
|
{
|
||||||
ReportError($"Failed to set {constantTypeSchema.Name}.{propName}", constant);
|
ReportError($"Failed to get canonical instance '{canonicalName}' from '{constant.TypeName}'", constant);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop.SetValue(ref constantValue, propValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (constant is BinaryEncodedConstantDirective binaryEncodedConstant)
|
||||||
MarkupConstantPersistMode mode;
|
|
||||||
if (constantTypeSchema.SupportsBinaryEncoding)
|
|
||||||
{
|
{
|
||||||
mode = MarkupConstantPersistMode.Binary;
|
if (!constantTypeSchema.SupportsBinaryEncoding)
|
||||||
|
{
|
||||||
|
ReportError($"Constant was binary-encoded, but {constant.TypeName} does not support binary encoding.", constant);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentBuffer = binaryEncodedConstant.Content;
|
||||||
|
|
||||||
|
ByteCodeWriter binaryConstantWrtier = new();
|
||||||
|
binaryConstantWrtier.Write(contentBuffer, (uint)contentBuffer.Length);
|
||||||
|
|
||||||
|
var binaryConstantReader = binaryConstantWrtier.CreateReader();
|
||||||
|
constantValue = constantTypeSchema.DecodeBinary(binaryConstantReader);
|
||||||
|
|
||||||
persistData = constantValue;
|
persistData = constantValue;
|
||||||
|
mode = MarkupConstantPersistMode.Binary;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mode = MarkupConstantPersistMode.FromString;
|
ReportError($"Constant of type '{constant.TypeName}' was not encoded in a recognized format.", constant);
|
||||||
if (persistData is null)
|
continue;
|
||||||
throw new Exception($"{constant.Name} cannot be persisted as a string without persist data.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var constantIndex = (ushort)constantsTable.Add(constantTypeSchema, constantValue, mode, persistData);
|
var constantIndex = (ushort)constantsTable.Add(constantTypeSchema, constantValue, mode, persistData);
|
||||||
|
|||||||
@@ -328,6 +328,8 @@ public class Disassembler
|
|||||||
return new StringEncodedConstantDirective(constantName, qualifiedTypeName, encodedValue);
|
return new StringEncodedConstantDirective(constantName, qualifiedTypeName, encodedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: How are canonical instances usually handled? Are they always loaded by
|
||||||
|
// converting the canonical name as a string to the base type?
|
||||||
// Custom handling for ILayout
|
// Custom handling for ILayout
|
||||||
if (constantValue is Layout.ILayout constantLayout && Layout.PredefinedLayouts.TryConvertToString(constantLayout, out var constantLayoutString))
|
if (constantValue is Layout.ILayout constantLayout && Layout.PredefinedLayouts.TryConvertToString(constantLayout, out var constantLayoutString))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user