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)
|
|
|
|
{
|
2020-03-09 06:34:16 -07:00
|
|
|
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);
|
|
|
|
|
2020-03-09 06:34:16 -07:00
|
|
|
Type attrType = Type.[Friend]GetType(typeId);
|
2019-08-23 11:56:54 -07:00
|
|
|
TypeInstance attrTypeInst = attrType as TypeInstance;
|
2020-03-09 06:34:16 -07:00
|
|
|
MethodInfo methodInfo = .(attrTypeInst, attrTypeInst.[Friend]mMethodDataPtr + methodIdx);
|
2019-08-23 11:56:54 -07:00
|
|
|
|
2022-02-12 08:05:47 -05:00
|
|
|
Object[] args = scope Object[methodInfo.[Friend]mData.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,
|
2020-08-23 07:43:16 -07:00
|
|
|
.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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|