Files
Cpp2IL/Cpp2IL.Core/Model/CustomAttributes/CustomAttributePrimitiveParameter.cs
T

104 lines
4.1 KiB
C#

using System;
using System.Globalization;
using System.IO;
using System.Text;
using Cpp2IL.Core.Extensions;
using Cpp2IL.Core.Model.Contexts;
using LibCpp2IL.BinaryStructures;
namespace Cpp2IL.Core.Model.CustomAttributes;
/// <summary>
/// Represents a custom attribute parameter which is an instance of IConvertible (that is, a numeric type, or a nullable string)
/// </summary>
public class CustomAttributePrimitiveParameter : BaseCustomAttributeParameter
{
public readonly Il2CppTypeEnum PrimitiveType;
public IConvertible? PrimitiveValue;
public CustomAttributePrimitiveParameter(Il2CppTypeEnum primitiveType, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
{
PrimitiveType = primitiveType;
}
public CustomAttributePrimitiveParameter(IConvertible value, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
{
PrimitiveValue = value;
PrimitiveType = value switch
{
string => Il2CppTypeEnum.IL2CPP_TYPE_STRING,
bool => Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN,
char => Il2CppTypeEnum.IL2CPP_TYPE_CHAR,
sbyte _ => Il2CppTypeEnum.IL2CPP_TYPE_I1,
byte _ => Il2CppTypeEnum.IL2CPP_TYPE_U1,
short _ => Il2CppTypeEnum.IL2CPP_TYPE_I2,
ushort _ => Il2CppTypeEnum.IL2CPP_TYPE_U2,
int _ => Il2CppTypeEnum.IL2CPP_TYPE_I4,
uint _ => Il2CppTypeEnum.IL2CPP_TYPE_U4,
long _ => Il2CppTypeEnum.IL2CPP_TYPE_I8,
ulong _ => Il2CppTypeEnum.IL2CPP_TYPE_U8,
float _ => Il2CppTypeEnum.IL2CPP_TYPE_R4,
double _ => Il2CppTypeEnum.IL2CPP_TYPE_R8,
_ => throw new ArgumentException("Unsupported primitive type")
};
}
public override void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisContext context)
{
switch (PrimitiveType)
{
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
PrimitiveValue = reader.ReadBoolean();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
PrimitiveValue = reader.ReadChar();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
PrimitiveValue = reader.ReadSByte();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
PrimitiveValue = reader.ReadByte();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
PrimitiveValue = reader.ReadInt16();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
PrimitiveValue = reader.ReadUInt16();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
PrimitiveValue = reader.BaseStream.ReadUnityCompressedInt();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
PrimitiveValue = reader.BaseStream.ReadUnityCompressedUint();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
PrimitiveValue = reader.ReadInt64();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
PrimitiveValue = reader.ReadUInt64();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
PrimitiveValue = reader.ReadSingle();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
PrimitiveValue = reader.ReadDouble();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
var strLength = reader.BaseStream.ReadUnityCompressedInt();
PrimitiveValue = strLength > 0 ? Encoding.UTF8.GetString(reader.ReadBytes(strLength)) : null;
break;
default:
throw new Exception("CustomAttributePrimitiveParameter constructed with a non-primitive type: " + PrimitiveType);
}
}
public override string ToString()
{
if(PrimitiveValue is string s)
return $"\"{s}\"";
return PrimitiveValue?.ToString(CultureInfo.InvariantCulture) ?? "null";
}
}