mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 11:32:59 +00:00
96 lines
2.9 KiB
C#
96 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text;
|
|
using Esiur.Data;
|
|
|
|
namespace Esiur.Resource.Template;
|
|
|
|
public class ConstantTemplate : MemberTemplate
|
|
{
|
|
public readonly object Value;
|
|
//public readonly byte[] ValueData;
|
|
public readonly string Annotation;
|
|
public readonly RepresentationType ValueType;
|
|
|
|
public FieldInfo FieldInfo { get; set; }
|
|
|
|
public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string annotation)
|
|
: base(template, index, name, inherited)
|
|
{
|
|
Annotation = annotation;
|
|
ValueType = valueType;
|
|
Value = value;
|
|
//try
|
|
//{
|
|
// Codec.Compose(value, null);
|
|
// Value = value;
|
|
//}
|
|
//catch
|
|
//{
|
|
// throw new Exception($"Constant `{template.ClassName}.{name}` can't be serialized.");
|
|
//}
|
|
}
|
|
|
|
public override byte[] Compose()
|
|
{
|
|
var name = base.Compose();
|
|
|
|
var hdr = Inherited ? (byte)0x80 : (byte)0;
|
|
|
|
|
|
if (Annotation != null)
|
|
{
|
|
var exp = DC.ToBytes(Annotation);
|
|
hdr |= 0x70;
|
|
return new BinaryList()
|
|
.AddUInt8(hdr)
|
|
.AddUInt8((byte)name.Length)
|
|
.AddUInt8Array(name)
|
|
.AddUInt8Array(ValueType.Compose())
|
|
.AddUInt8Array(Codec.Compose(Value, null))
|
|
.AddInt32(exp.Length)
|
|
.AddUInt8Array(exp)
|
|
.ToArray();
|
|
}
|
|
else
|
|
{
|
|
hdr |= 0x60;
|
|
|
|
return new BinaryList()
|
|
.AddUInt8(hdr)
|
|
.AddUInt8((byte)name.Length)
|
|
.AddUInt8Array(name)
|
|
.AddUInt8Array(ValueType.Compose())
|
|
.AddUInt8Array(Codec.Compose(Value, null))
|
|
.ToArray();
|
|
}
|
|
}
|
|
|
|
|
|
public static ConstantTemplate MakeConstantTemplate(Type type, FieldInfo ci, PublicAttribute publicAttr, byte index = 0, TypeTemplate typeTemplate = null)
|
|
{
|
|
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
|
var nullableAttr = ci.GetCustomAttribute<NullableAttribute>(true);
|
|
|
|
var valueType = RepresentationType.FromType(ci.FieldType);
|
|
|
|
if (valueType == null)
|
|
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
|
|
|
|
var value = ci.GetValue(null);
|
|
|
|
if (typeTemplate?.Type == TemplateType.Enum)
|
|
value = Convert.ChangeType(value, ci.FieldType.GetEnumUnderlyingType());
|
|
|
|
var ct = new ConstantTemplate(typeTemplate, index, publicAttr?.Name ?? ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
|
|
ct.FieldInfo = ci;
|
|
|
|
return ct;
|
|
|
|
}
|
|
|
|
}
|
|
|