public void EmitArrayShapeAtCurrentIndexStack(BlobBuilder signatureBuilder, int rank) { var shapeEncoder = new ArrayShapeEncoder(signatureBuilder); bool emittedWithShape = false; if (!Complete) { if (_embeddedDataIndex < _embeddedData.Length) { if (_embeddedData[_embeddedDataIndex].kind == EmbeddedSignatureDataKind.ArrayShape) { string indexData = string.Join(".", _indexStack); var arrayShapePossibility = _embeddedData[_embeddedDataIndex].index.Split('|'); if (arrayShapePossibility[0] == indexData) { string[] boundsStr = arrayShapePossibility[1].Split(',', StringSplitOptions.RemoveEmptyEntries); string[] loBoundsStr = arrayShapePossibility[2].Split(',', StringSplitOptions.RemoveEmptyEntries); int[] bounds = new int[boundsStr.Length]; int[] loBounds = new int[loBoundsStr.Length]; for (int i = 0; i < boundsStr.Length; i++) { bounds[i] = Int32.Parse(boundsStr[i]); } for (int i = 0; i < loBoundsStr.Length; i++) { loBounds[i] = Int32.Parse(loBoundsStr[i]); } shapeEncoder.Shape(rank, ImmutableArray.Create(bounds), ImmutableArray.Create(loBounds)); _embeddedDataIndex++; return; } } } } if (!emittedWithShape) { shapeEncoder.Shape(rank, ImmutableArray <int> .Empty, GetZeroedImmutableArrayOfSize(rank)); } }
private void EncodeType(BlobBuilder blobBuilder, TypeDesc type) { if (type.IsPrimitive) { SignatureTypeCode primitiveCode; switch (type.Category) { case TypeFlags.Void: primitiveCode = SignatureTypeCode.Void; break; case TypeFlags.Boolean: primitiveCode = SignatureTypeCode.Boolean; break; case TypeFlags.Char: primitiveCode = SignatureTypeCode.Char; break; case TypeFlags.SByte: primitiveCode = SignatureTypeCode.SByte; break; case TypeFlags.Byte: primitiveCode = SignatureTypeCode.Byte; break; case TypeFlags.Int16: primitiveCode = SignatureTypeCode.Int16; break; case TypeFlags.UInt16: primitiveCode = SignatureTypeCode.UInt16; break; case TypeFlags.Int32: primitiveCode = SignatureTypeCode.Int32; break; case TypeFlags.UInt32: primitiveCode = SignatureTypeCode.UInt32; break; case TypeFlags.Int64: primitiveCode = SignatureTypeCode.Int64; break; case TypeFlags.UInt64: primitiveCode = SignatureTypeCode.UInt64; break; case TypeFlags.IntPtr: primitiveCode = SignatureTypeCode.IntPtr; break; case TypeFlags.UIntPtr: primitiveCode = SignatureTypeCode.UIntPtr; break; case TypeFlags.Single: primitiveCode = SignatureTypeCode.Single; break; case TypeFlags.Double: primitiveCode = SignatureTypeCode.Double; break; default: throw new Exception("Unknown primitive type"); } blobBuilder.WriteByte((byte)primitiveCode); } else if (type.IsSzArray) { blobBuilder.WriteByte((byte)SignatureTypeCode.SZArray); EncodeType(blobBuilder, type.GetParameterType()); } else if (type.IsArray) { var arrayType = (ArrayType)type; blobBuilder.WriteByte((byte)SignatureTypeCode.Array); EncodeType(blobBuilder, type.GetParameterType()); var shapeEncoder = new ArrayShapeEncoder(blobBuilder); // TODO Add support for non-standard array shapes shapeEncoder.Shape(arrayType.Rank, default(ImmutableArray <int>), default(ImmutableArray <int>)); } else if (type.IsPointer) { blobBuilder.WriteByte((byte)SignatureTypeCode.Pointer); EncodeType(blobBuilder, type.GetParameterType()); } else if (type.IsFunctionPointer) { FunctionPointerType fnptrType = (FunctionPointerType)type; EncodeMethodSignature(blobBuilder, fnptrType.Signature); } else if (type.IsByRef) { blobBuilder.WriteByte((byte)SignatureTypeCode.ByReference); EncodeType(blobBuilder, type.GetParameterType()); } else if (type.IsObject) { blobBuilder.WriteByte((byte)SignatureTypeCode.Object); } else if (type.IsString) { blobBuilder.WriteByte((byte)SignatureTypeCode.String); } else if (type.IsWellKnownType(WellKnownType.TypedReference)) { blobBuilder.WriteByte((byte)SignatureTypeCode.TypedReference); } else if (type.IsWellKnownType(WellKnownType.Void)) { blobBuilder.WriteByte((byte)SignatureTypeCode.Void); } else if (type is SignatureVariable) { SignatureVariable sigVar = (SignatureVariable)type; SignatureTypeCode code = sigVar.IsMethodSignatureVariable ? SignatureTypeCode.GenericMethodParameter : SignatureTypeCode.GenericTypeParameter; blobBuilder.WriteByte((byte)code); blobBuilder.WriteCompressedInteger(sigVar.Index); } else if (type is InstantiatedType) { blobBuilder.WriteByte((byte)SignatureTypeCode.GenericTypeInstance); EncodeType(blobBuilder, type.GetTypeDefinition()); blobBuilder.WriteCompressedInteger(type.Instantiation.Length); foreach (var instantiationArg in type.Instantiation) { EncodeType(blobBuilder, instantiationArg); } } else if (type is MetadataType) { var metadataType = (MetadataType)type; // Must be class or valuetype blobBuilder.WriteByte(type.IsValueType ? (byte)SignatureTypeKind.ValueType : (byte)SignatureTypeKind.Class); int codedIndex = CodedIndex.TypeDefOrRef(GetTypeRef(metadataType)); blobBuilder.WriteCompressedInteger(codedIndex); } else { throw new Exception("Unexpected type"); } }
public void Array(out SignatureTypeEncoder elementType, out ArrayShapeEncoder arrayShape) { Builder.WriteByte((byte)SignatureTypeCode.Array); elementType = this; arrayShape = new ArrayShapeEncoder(Builder); }
public void ArrayShapeEncoder_Shape() { var b = new BlobBuilder(); var e = new ArrayShapeEncoder(b); Assert.Same(b, e.Builder); e.Shape(ushort.MaxValue, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty); AssertEx.Equal(new byte[] { 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(0x0A), ImmutableArray <int> .Empty); AssertEx.Equal(new byte[] { 0x03, 0x01, 0x0A, 0x00 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(0x0A, 0x0B), ImmutableArray.Create(0x02, 0x03)); AssertEx.Equal(new byte[] { 0x03, 0x02, 0x0A, 0x0B, 0x02, 0x04, 0x06 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray <int> .Empty, ImmutableArray.Create(-2, -1)); AssertEx.Equal(new byte[] { 0x03, 0x00, 0x02, 0x7D, 0x7F }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue), ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue, BlobWriterImpl.MaxSignedCompressedIntegerValue)); AssertEx.Equal(new byte[] { 0x03, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0x02, 0xC0, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFE }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentNullException>(() => e.Shape(1, default(ImmutableArray <int>), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(0, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(-1, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(ushort.MaxValue + 1, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(1, 2, 3), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(1, 2, 3))); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(-1), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue + 1), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue - 1))); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(BlobWriterImpl.MaxSignedCompressedIntegerValue + 1))); }
public void ArrayShapeEncoder_Shape() { var b = new BlobBuilder(); var e = new ArrayShapeEncoder(b); Assert.Same(b, e.Builder); e.Shape(ushort.MaxValue, ImmutableArray<int>.Empty, ImmutableArray<int>.Empty); AssertEx.Equal(new byte[] { 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(0x0A), ImmutableArray<int>.Empty); AssertEx.Equal(new byte[] { 0x03, 0x01, 0x0A, 0x00 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(0x0A, 0x0B), ImmutableArray.Create(0x02, 0x03)); AssertEx.Equal(new byte[] { 0x03, 0x02, 0x0A, 0x0B, 0x02, 0x04, 0x06 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray<int>.Empty, ImmutableArray.Create(-2, -1)); AssertEx.Equal(new byte[] { 0x03, 0x00, 0x02, 0x7D, 0x7F }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue), ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue, BlobWriterImpl.MaxSignedCompressedIntegerValue)); AssertEx.Equal(new byte[] { 0x03, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0x02, 0xC0, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFE }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.Shape(1, default(ImmutableArray<int>), ImmutableArray<int>.Empty)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(0, ImmutableArray<int>.Empty, ImmutableArray<int>.Empty)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(-1, ImmutableArray<int>.Empty, ImmutableArray<int>.Empty)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(ushort.MaxValue + 1, ImmutableArray<int>.Empty, ImmutableArray<int>.Empty)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(1,2,3), ImmutableArray<int>.Empty)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray<int>.Empty, ImmutableArray.Create(1,2,3))); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(-1), ImmutableArray<int>.Empty)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue + 1), ImmutableArray<int>.Empty)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray<int>.Empty, ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue - 1))); Assert.Throws<ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray<int>.Empty, ImmutableArray.Create(BlobWriterImpl.MaxSignedCompressedIntegerValue + 1))); }