public void CreateArrayField() { // set up temp assembly. var assembly = Utilities.CreateTempNetAssembly(); var typeSystem = assembly.NetDirectory.MetadataHeader.TypeSystem; var tableStream = assembly.NetDirectory.MetadataHeader.GetStream<TableStream>(); var fieldTable = tableStream.GetTable<FieldDefinition>(); var importer = new ReferenceImporter(tableStream); // create field. var arraySignature = new ArrayTypeSignature(typeSystem.Int32); arraySignature.Dimensions.Add(new ArrayDimension(2, 1)); arraySignature.Dimensions.Add(new ArrayDimension(2)); arraySignature.Dimensions.Add(new ArrayDimension()); var field = new FieldDefinition(FieldName, FieldAttributes.Public | FieldAttributes.Static, new FieldSignature(importer.ImportTypeSignature(arraySignature))); fieldTable.Add(field); // build and validate. assembly = Utilities.RebuildNetAssembly(assembly); fieldTable = assembly.NetDirectory.MetadataHeader.GetStream<TableStream>().GetTable<FieldDefinition>(); field = fieldTable.First(x => x.Name == FieldName); Assert.IsInstanceOfType(field.Signature.FieldType, typeof(ArrayTypeSignature)); Utilities.ValidateType(arraySignature, field.Signature.FieldType); }
private static TypeSignature ReadTypeSignature( MetadataImage image, IBinaryStreamReader reader, RecursionProtection protection) { var elementType = (ElementType)reader.ReadByte(); switch (elementType) { case ElementType.Array: return(ArrayTypeSignature.FromReader(image, reader, protection)); case ElementType.Boxed: return(BoxedTypeSignature.FromReader(image, reader, protection)); case ElementType.ByRef: return(ByReferenceTypeSignature.FromReader(image, reader, protection)); case ElementType.CModOpt: return(OptionalModifierSignature.FromReader(image, reader, protection)); case ElementType.CModReqD: return(RequiredModifierSignature.FromReader(image, reader, protection)); case ElementType.Class: return(TypeDefOrRefSignature.FromReader(image, reader, protection)); case ElementType.FnPtr: return(FunctionPointerTypeSignature.FromReader(image, reader, protection)); case ElementType.GenericInst: return(GenericInstanceTypeSignature.FromReader(image, reader, protection)); case ElementType.MVar: return(GenericParameterSignature.FromReader(image, reader, GenericParameterType.Method)); case ElementType.Pinned: return(PinnedTypeSignature.FromReader(image, reader, protection)); case ElementType.Ptr: return(PointerTypeSignature.FromReader(image, reader, protection)); case ElementType.Sentinel: return(SentinelTypeSignature.FromReader(image, reader, protection)); case ElementType.SzArray: return(SzArrayTypeSignature.FromReader(image, reader, protection)); case ElementType.ValueType: var type = TypeDefOrRefSignature.FromReader(image, reader, protection); type.IsValueType = true; return(type); case ElementType.Var: return(GenericParameterSignature.FromReader(image, reader, GenericParameterType.Type)); default: return(MsCorLibTypeSignature.FromElementType(image, elementType)); } }
public static TypeSignature FromReader(MetadataHeader header, IBinaryStreamReader reader) { var elementType = (ElementType)reader.ReadByte(); switch (elementType) { case ElementType.Array: return(ArrayTypeSignature.FromReader(header, reader)); case ElementType.Boxed: return(BoxedTypeSignature.FromReader(header, reader)); case ElementType.ByRef: return(ByReferenceTypeSignature.FromReader(header, reader)); case ElementType.CModOpt: return(OptionalModifierSignature.FromReader(header, reader)); case ElementType.CModReqD: return(RequiredModifierSignature.FromReader(header, reader)); case ElementType.Class: return(TypeDefOrRefSignature.FromReader(header, reader)); case ElementType.FnPtr: return(FunctionPointerTypeSignature.FromReader(header, reader)); case ElementType.GenericInst: return(GenericInstanceTypeSignature.FromReader(header, reader)); case ElementType.MVar: return(GenericParameterSignature.FromReader(header, reader, GenericParameterType.Method)); case ElementType.Pinned: return(PinnedTypeSignature.FromReader(header, reader)); case ElementType.Ptr: return(PointerTypeSignature.FromReader(header, reader)); case ElementType.Sentinel: return(SentinelTypeSignature.FromReader(header, reader)); case ElementType.SzArray: return(SzArrayTypeSignature.FromReader(header, reader)); case ElementType.ValueType: var type = TypeDefOrRefSignature.FromReader(header, reader); type.IsValueType = true; return(type); case ElementType.Var: return(GenericParameterSignature.FromReader(header, reader, GenericParameterType.Type)); default: return(MsCorLibTypeSignature.FromElementType(header, elementType)); } throw new NotSupportedException(); }
public override TypeSignature InstantiateGenericTypes(IGenericContext context) { var arrayType = new ArrayTypeSignature(BaseType.InstantiateGenericTypes(context)); foreach (var dimension in Dimensions) { arrayType.Dimensions.Add(new ArrayDimension(dimension.Size, dimension.LowerBound)); } return(arrayType); }
public void MatchArrayTypeSignatures() { var arrayType1 = new ArrayTypeSignature(CreateTypeSig1()); arrayType1.Dimensions.Add(new ArrayDimension(null, 0)); arrayType1.Dimensions.Add(new ArrayDimension(null, 0)); var arrayType2 = new ArrayTypeSignature(CreateTypeSig1()); arrayType2.Dimensions.Add(new ArrayDimension(null, 0)); arrayType2.Dimensions.Add(new ArrayDimension(null, 0)); var arrayType3 = new ArrayTypeSignature(CreateTypeSig1()); arrayType3.Dimensions.Add(new ArrayDimension(null, 0)); arrayType3.Dimensions.Add(new ArrayDimension(null, 1)); VerifyMatching(arrayType1, arrayType2, arrayType3); }
public static new ArrayTypeSignature FromReader(MetadataHeader header, IBinaryStreamReader reader) { long position = reader.Position; var signature = new ArrayTypeSignature(TypeSignature.FromReader(header, reader)) { StartOffset = position }; uint rank; if (!reader.TryReadCompressedUInt32(out rank)) return signature; uint numSizes; if (!reader.TryReadCompressedUInt32(out numSizes)) return signature; var sizes = new uint[numSizes]; for (int i = 0; i < numSizes; i++) { if (!reader.TryReadCompressedUInt32(out sizes[i])) return signature; } uint numLoBounds; if (!reader.TryReadCompressedUInt32(out numLoBounds)) return signature; var loBounds = new uint[numLoBounds]; for (int i = 0; i < numLoBounds; i++) { if (!reader.TryReadCompressedUInt32(out loBounds[i])) return signature; } for (int i = 0; i < rank; i++) { var dimension = new ArrayDimension(); if (i < numSizes) dimension.Size = (int)sizes[i]; if (i < numLoBounds) dimension.LowerBound = (int)loBounds[i]; signature.Dimensions.Add(dimension); } return signature; }
/// <summary> /// Reads a single array type signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the array was defined in.</param> /// <param name="reader">The reader to use.</param> /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param> /// <returns>The read array.</returns> public static ArrayTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader, RecursionProtection protection) { var signature = new ArrayTypeSignature(TypeSignature.FromReader(image, reader, false, 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++) { var dimension = new ArrayDimension(); if (i < numSizes) { dimension.Size = (int)sizes[i]; } if (i < numLoBounds) { dimension.LowerBound = (int)loBounds[i]; } signature.Dimensions.Add(dimension); } return(signature); }
public new static ArrayTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader) { long position = reader.Position; var signature = new ArrayTypeSignature(TypeSignature.FromReader(image, reader)); uint rank; if (!reader.TryReadCompressedUInt32(out rank)) { return(signature); } uint numSizes; if (!reader.TryReadCompressedUInt32(out numSizes)) { return(signature); } var sizes = new uint[numSizes]; for (int i = 0; i < numSizes; i++) { if (!reader.TryReadCompressedUInt32(out sizes[i])) { return(signature); } } uint numLoBounds; if (!reader.TryReadCompressedUInt32(out numLoBounds)) { return(signature); } var loBounds = new uint[numLoBounds]; for (int i = 0; i < numLoBounds; i++) { if (!reader.TryReadCompressedUInt32(out loBounds[i])) { return(signature); } } for (int i = 0; i < rank; i++) { var dimension = new ArrayDimension(); if (i < numSizes) { dimension.Size = (int)sizes[i]; } if (i < numLoBounds) { dimension.LowerBound = (int)loBounds[i]; } signature.Dimensions.Add(dimension); } return(signature); }
private ArrayTypeSignature ImportArrayTypeSignature(ArrayTypeSignature signature) { var newSignature = new ArrayTypeSignature(ImportTypeSignature(signature.BaseType)) { IsValueType = signature.IsValueType }; foreach (var dimension in signature.Dimensions) { var newDimension = new ArrayDimension(); if (dimension.Size.HasValue) newDimension.Size = dimension.Size.Value; if (dimension.LowerBound.HasValue) newDimension.LowerBound = dimension.LowerBound.Value; newSignature.Dimensions.Add(newDimension); } return newSignature; }
private ArrayTypeSignature ImportArrayTypeSignature(Type arrayType) { var newSignature = new ArrayTypeSignature(ImportTypeSignature(arrayType.GetElementType())) { IsValueType = arrayType.IsValueType }; for (int i = 0; i < arrayType.GetArrayRank(); i++) newSignature.Dimensions.Add(new ArrayDimension()); return newSignature; }
/// <summary> /// Determines whether two types are considered equal according to their signature. /// </summary> /// <param name="signature1">The first type to compare.</param> /// <param name="signature2">The second type to compare.</param> /// <returns><c>True</c> if the types are considered equal, <c>False</c> otherwise.</returns> public bool MatchTypes(ArrayTypeSignature signature1, ArrayTypeSignature signature2) { if (signature1 == null && signature2 == null) return true; if (signature1 == null || signature2 == null) return false; return MatchTypes(signature1.BaseType, signature2.BaseType) && signature1.Dimensions.Count == signature2.Dimensions.Count && signature1.Dimensions.Where((d, i) => MatchArrayDimensions(d, signature2.Dimensions[i])).Count() == signature1.Dimensions.Count; }