/// <summary> /// Reads a type signature from a blob reader. /// </summary> /// <param name="module">The module containing the blob signature.</param> /// <param name="reader">The blob signature reader.</param> /// <param name="protection">The object responsible for detecting infinite recursion.</param> /// <returns>The type signature.</returns> /// <exception cref="ArgumentOutOfRangeException">Occurs when the blob reader points to an element type that is /// invalid or unsupported.</exception> public static TypeSignature FromReader(ModuleDefinition module, IBinaryStreamReader reader, RecursionProtection protection) { var elementType = (ElementType)reader.ReadByte(); switch (elementType) { case ElementType.Void: case ElementType.Boolean: case ElementType.Char: case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.String: case ElementType.I: case ElementType.U: case ElementType.TypedByRef: case ElementType.Object: return(module.CorLibTypeFactory.FromElementType(elementType)); case ElementType.ValueType: return(new TypeDefOrRefSignature(ReadTypeDefOrRef(module, reader, protection, false), true)); case ElementType.Class: return(new TypeDefOrRefSignature(ReadTypeDefOrRef(module, reader, protection, false), false)); case ElementType.Ptr: return(new PointerTypeSignature(FromReader(module, reader, protection))); case ElementType.ByRef: return(new ByReferenceTypeSignature(FromReader(module, reader, protection))); case ElementType.Var: return(new GenericParameterSignature(module, GenericParameterType.Type, (int)reader.ReadCompressedUInt32())); case ElementType.MVar: return(new GenericParameterSignature(module, GenericParameterType.Method, (int)reader.ReadCompressedUInt32())); case ElementType.Array: return(ArrayTypeSignature.FromReader(module, reader, protection)); case ElementType.GenericInst: return(GenericInstanceTypeSignature.FromReader(module, reader, protection)); case ElementType.FnPtr: throw new NotImplementedException(); case ElementType.SzArray: return(new SzArrayTypeSignature(FromReader(module, reader, protection))); case ElementType.CModReqD: return(new CustomModifierTypeSignature( ReadTypeDefOrRef(module, reader, protection, true), true, FromReader(module, reader, protection))); case ElementType.CModOpt: return(new CustomModifierTypeSignature( ReadTypeDefOrRef(module, reader, protection, true), false, FromReader(module, reader, protection))); case ElementType.Sentinel: return(new SentinelTypeSignature()); case ElementType.Pinned: return(new PinnedTypeSignature(FromReader(module, reader, protection))); case ElementType.Boxed: return(new BoxedTypeSignature(FromReader(module, reader, protection))); case ElementType.Internal: IntPtr address = IntPtr.Size switch { 4 => new IntPtr(reader.ReadInt32()), _ => new IntPtr(reader.ReadInt64()) }; //Get Internal Method Through Reflection var GetTypeFromHandleUnsafeReflection = typeof(Type) .GetMethod("GetTypeFromHandleUnsafe", ((BindingFlags)(-1)), null, new[] { typeof(IntPtr) }, null); //Invoke It To Get The Value var Type = (Type)GetTypeFromHandleUnsafeReflection?.Invoke(null, new object[] { address }); //Import it return(new TypeDefOrRefSignature(new ReferenceImporter(module).ImportType((Type)))); default: throw new ArgumentOutOfRangeException($"Invalid or unsupported element type {elementType}."); } }
internal new static ArrayTypeSignature FromReader(ModuleDefinition parentModule, IBinaryStreamReader reader, RecursionProtection protection) { var signature = new ArrayTypeSignature(TypeSignature.FromReader(parentModule, reader, protection)); // Rank if (!reader.TryReadCompressedUInt32(out uint rank)) { return(signature); } // Sizes. if (!reader.TryReadCompressedUInt32(out uint numSizes)) { return(signature); } var sizes = new List <uint>(); for (int i = 0; i < numSizes; i++) { if (!reader.TryReadCompressedUInt32(out uint size)) { return(signature); } sizes.Add(size); } // Lower bounds. if (!reader.TryReadCompressedUInt32(out uint numLoBounds)) { return(signature); } var loBounds = new List <uint>(); for (int i = 0; i < numLoBounds; i++) { if (!reader.TryReadCompressedUInt32(out uint bound)) { return(signature); } loBounds.Add(bound); } // Create dimensions. for (int i = 0; i < rank; i++) { int?size = null, lowerBound = null; if (i < numSizes) { size = (int)sizes[i]; } if (i < numLoBounds) { lowerBound = (int)loBounds[i]; } signature.Dimensions.Add(new ArrayDimension(size, lowerBound)); } return(signature); }