1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-17 07:44:09 +02:00
Beef/BeefLibs/corlib/src/Reflection/AttributeInfo.bf

117 lines
3 KiB
Beef
Raw Normal View History

2019-08-23 11:56:54 -07:00
namespace System.Reflection
{
class AttributeInfo
{
static mixin Decode<T2>(void* data)
{
*((*(T2**)&data)++)
}
2021-01-11 09:41:43 -08:00
public static bool HasCustomAttribute(void* inAttrData, Type attributeType)
2019-08-23 11:56:54 -07:00
{
2021-01-11 09:41:43 -08:00
TypeId findTypeId = attributeType.[Friend]mTypeId;
void* data = inAttrData;
data++;
uint8 count = Decode!<uint8>(data);
for (int32 attrIdx = 0; attrIdx < count; attrIdx++)
AttrBlock:
{
void* startPtr = data;
var len = Decode!<uint16>(data);
void* endPtr = (uint8*)startPtr + len;
var typeId = Decode!<TypeId>(data);
if (typeId == findTypeId)
return true;
data = endPtr;
}
return false;
}
2019-08-23 11:56:54 -07:00
2021-01-11 09:41:43 -08:00
public static Result<void> GetCustomAttribute(void* inAttrData, Type attributeType, Object targetAttr)
{
TypeId findTypeId = attributeType.[Friend]mTypeId;
2019-08-23 11:56:54 -07:00
void* data = inAttrData;
data++;
uint8 count = Decode!<uint8>(data);
for (int32 attrIdx = 0; attrIdx < count; attrIdx++)
AttrBlock:
{
void* startPtr = data;
var len = Decode!<uint16>(data);
void* endPtr = (uint8*)startPtr + len;
var typeId = Decode!<TypeId>(data);
if (typeId != findTypeId)
{
data = endPtr;
continue;
}
var methodIdx = Decode!<uint16>(data);
Type attrType = Type.[Friend]GetType(typeId);
2019-08-23 11:56:54 -07:00
TypeInstance attrTypeInst = attrType as TypeInstance;
MethodInfo methodInfo = .(attrTypeInst, attrTypeInst.[Friend]mMethodDataPtr + methodIdx);
2019-08-23 11:56:54 -07:00
Object[] args = scope Object[methodInfo.[Friend]mMethodData.mParamCount];
2019-08-23 11:56:54 -07:00
int argIdx = 0;
while (data < endPtr)
{
var attrDataType = Decode!<TypeCode>(data);
switch (attrDataType)
{
case .Int8,
.UInt8,
.Char8,
.Boolean:
2019-08-23 11:56:54 -07:00
let attrData = Decode!<int8>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Int16,
.UInt16,
.Char16:
let attrData = Decode!<int16>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Int32,
.UInt32,
.Char32:
let attrData = Decode!<int32>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Float:
let attrData = Decode!<float>(data);
args[argIdx] = scope:AttrBlock box attrData;
case .Int64,
.UInt64,
.Double:
let attrData = Decode!<int64>(data);
args[argIdx] = scope:AttrBlock box attrData;
2022-01-14 07:08:09 -05:00
case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf
2021-11-02 11:32:06 -07:00
let argTypeId = Decode!<int32>(data);
args[argIdx] = Type.[Friend]GetType((.)argTypeId);
2019-08-23 11:56:54 -07:00
case (TypeCode)255:
let stringId = Decode!<int32>(data);
String str = String.[Friend]sIdStringLiterals[stringId];
args[argIdx] = str;
default:
Runtime.FatalError("Not handled");
}
argIdx++;
}
2021-12-27 14:02:51 -05:00
if (methodInfo.Invoke(targetAttr, params args) case .Ok(var val))
val.Dispose();
2019-08-23 11:56:54 -07:00
return .Ok;
}
return .Err;
}
}
}