mirror of
https://github.com/LukeFZ/Il2CppInspectorRedux.git
synced 2026-03-22 00:18:18 +05:00
use IndexOf in IndexType tag parsing to handle ParameterIndex and GenericParameterIndex properly
This commit is contained in:
@@ -1,53 +1,67 @@
|
||||
using VersionedSerialization;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using VersionedSerialization;
|
||||
|
||||
namespace Il2CppInspector.Next.Metadata;
|
||||
|
||||
file static class Il2CppMetadataIndex
|
||||
{
|
||||
public const int Invalid = -1;
|
||||
public const char NumberZeroChar = '0';
|
||||
}
|
||||
|
||||
public interface IIndexType<T> where T
|
||||
: IIndexType<T>, allows ref struct
|
||||
{
|
||||
public static abstract string TagPrefix { get; }
|
||||
|
||||
private static string TagSize4 => $"{T.TagPrefix}4";
|
||||
private static string TagSize2 => $"{T.TagPrefix}2";
|
||||
private static string TagSize1 => $"{T.TagPrefix}1";
|
||||
|
||||
private static bool HasCustomSize(in StructVersion version)
|
||||
=> version.Tag != null
|
||||
&& (version.Tag.Contains(TagSize2)
|
||||
|| version.Tag.Contains(TagSize1));
|
||||
|
||||
public static int IndexSize(in StructVersion version = default, bool is32Bit = false)
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int GetSizeFromTag(in StructVersion version)
|
||||
{
|
||||
if (version.Tag != null && HasCustomSize(version))
|
||||
// Fallback to the default for unsupported configurations.
|
||||
if (version < MetadataVersions.V380 || version.Tag == null)
|
||||
{
|
||||
if (version.Tag.Contains(TagSize2))
|
||||
return sizeof(ushort);
|
||||
|
||||
if (version.Tag.Contains(TagSize1))
|
||||
return sizeof(byte);
|
||||
return sizeof(int);
|
||||
}
|
||||
|
||||
return sizeof(int);
|
||||
// Get the position of the size tag in the version tag.
|
||||
// Bail out if not found.
|
||||
var sizeTagPosition = version.Tag.IndexOf(T.TagPrefix, StringComparison.Ordinal);
|
||||
if (sizeTagPosition == -1)
|
||||
{
|
||||
return sizeof(int);
|
||||
}
|
||||
|
||||
// Get the number that follows immediately after the size tag, and convert it to the actual size.
|
||||
var numberChar = version.Tag[sizeTagPosition + T.TagPrefix.Length];
|
||||
return numberChar - Il2CppMetadataIndex.NumberZeroChar;
|
||||
}
|
||||
|
||||
public static int IndexSize(in StructVersion version = default, bool is32Bit = false)
|
||||
=> GetSizeFromTag(version);
|
||||
|
||||
public static int ReadIndex<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
|
||||
{
|
||||
if (version.Tag != null && HasCustomSize(version))
|
||||
{
|
||||
if (version.Tag.Contains(TagSize2))
|
||||
{
|
||||
var value = reader.ReadPrimitive<ushort>();
|
||||
return value == ushort.MaxValue ? -1 : value;
|
||||
}
|
||||
var size = GetSizeFromTag(in version);
|
||||
|
||||
if (version.Tag.Contains(TagSize1))
|
||||
{
|
||||
var value = reader.ReadPrimitive<byte>();
|
||||
return value == byte.MaxValue ? -1 : value;
|
||||
}
|
||||
int index;
|
||||
if (size == sizeof(int))
|
||||
{
|
||||
index = reader.ReadPrimitive<int>();
|
||||
}
|
||||
else if (size == sizeof(ushort))
|
||||
{
|
||||
var value = reader.ReadPrimitive<ushort>();
|
||||
index = value == ushort.MaxValue ? Il2CppMetadataIndex.Invalid : value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(size == sizeof(byte));
|
||||
|
||||
var value = reader.ReadPrimitive<byte>();
|
||||
index = value == byte.MaxValue ? Il2CppMetadataIndex.Invalid : value;
|
||||
}
|
||||
|
||||
return reader.ReadPrimitive<int>();
|
||||
return index;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user