public void WritePrimitive() { var writer = new BlobBuilder(17); writer.WriteUInt32(0x11223344); writer.WriteUInt16(0x5566); writer.WriteByte(0x77); writer.WriteUInt64(0x8899aabbccddeeff); writer.WriteInt32(-1); writer.WriteInt16(-2); writer.WriteSByte(-3); writer.WriteBoolean(true); writer.WriteBoolean(false); writer.WriteInt64(unchecked((long)0xfedcba0987654321)); writer.WriteDateTime(new DateTime(0x1112223334445556)); writer.WriteDecimal(102030405060.70m); writer.WriteDouble(double.NaN); writer.WriteSingle(float.NegativeInfinity); var guid = new Guid("01020304-0506-0708-090A-0B0C0D0E0F10"); writer.WriteBytes(guid.ToByteArray()); writer.WriteGuid(guid); AssertEx.Equal(new byte[] { 0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x77, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0x00, 0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE, 0x56, 0x55, 0x44, 0x34, 0x33, 0x22, 0x12, 0x11, 0x02, 0xD6, 0xE0, 0x9A, 0x94, 0x47, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x07, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x07, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }, writer.ToArray()); }
public static void Write( BlobBuilder writer, IReadOnlyList <Instruction> il, Func <string, StringHandle> getString, IReadOnlyDictionary <Guid, EntityHandle> typeHandles, IReadOnlyDictionary <ConstructorInfo, MemberReferenceHandle> ctorRefHandles, IReadOnlyDictionary <FieldInfo, FieldDefinitionHandle> fieldHandles, IReadOnlyDictionary <MethodInfo, MethodDefinitionHandle> methodHandles) { var targetOffsets = new ArrayMapper <int>(); //var offsetIndex = new Dictionary<int, int>(); for (var i = 0; i < il.Count; i++) { //offsetIndex.Add(il[i].Offset, i); var opCode = il[i].OpCode; opCode.WriteOpCode(writer.WriteByte); switch (opCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: var branches = (int[])il[i].Operand; writer.WriteInt32(branches.Length); for (var k = 0; k < branches.Length; k++) { var branchOffset = branches[k]; writer.WriteInt32(targetOffsets.Add( branchOffset + il[i].Offset + opCode.Size + 4 * (branches.Length + 1))); } break; case OperandType.ShortInlineBrTarget: var offset8 = (sbyte)il[i].Operand; // offset convention in IL: zero is at next instruction writer.WriteSByte((sbyte)targetOffsets.Add(offset8 + il[i].Offset + opCode.Size + 1)); break; case OperandType.InlineBrTarget: var offset32 = (int)il[i].Operand; // offset convention in IL: zero is at next instruction writer.WriteInt32(targetOffsets.Add(offset32 + il[i].Offset + opCode.Size + 4)); break; case OperandType.ShortInlineI: if (opCode == OpCodes.Ldc_I4_S) { writer.WriteSByte((sbyte)il[i].Operand); } else { writer.WriteByte((byte)il[i].Operand); } break; case OperandType.InlineI: writer.WriteInt32((int)il[i].Operand); break; case OperandType.ShortInlineR: writer.WriteSingle((float)il[i].Operand); break; case OperandType.InlineR: writer.WriteDouble((double)il[i].Operand); break; case OperandType.InlineI8: writer.WriteInt64((long)il[i].Operand); break; case OperandType.InlineSig: writer.WriteBytes((byte[])il[i].Operand); break; case OperandType.InlineString: writer.WriteInt32(MetadataTokens.GetToken(getString((string)il[i].Operand))); break; case OperandType.InlineType: case OperandType.InlineTok: case OperandType.InlineMethod: case OperandType.InlineField: switch (il[i].Operand) { case Type type: writer.WriteInt32(MetadataTokens.GetToken(typeHandles[type.GUID])); break; case ConstructorInfo constructorInfo: writer.WriteInt32(MetadataTokens.GetToken(ctorRefHandles[constructorInfo])); break; case FieldInfo fieldInfo: writer.WriteInt32(MetadataTokens.GetToken(fieldHandles[fieldInfo])); break; case MethodInfo methodInfo: writer.WriteInt32(MetadataTokens.GetToken(methodHandles[methodInfo])); break; default: throw new NotSupportedException(); } break; case OperandType.ShortInlineVar: var bLocalVariableInfo = il[i].Operand as LocalVariableInfo; var bParameterInfo = il[i].Operand as ParameterInfo; if (bLocalVariableInfo != null) { writer.WriteByte((byte)bLocalVariableInfo.LocalIndex); } else if (bParameterInfo != null) { writer.WriteByte((byte)bParameterInfo.Position); } else { throw new NotSupportedException(); } break; case OperandType.InlineVar: var sLocalVariableInfo = il[i].Operand as LocalVariableInfo; var sParameterInfo = il[i].Operand as ParameterInfo; if (sLocalVariableInfo != null) { writer.WriteUInt16((ushort)sLocalVariableInfo.LocalIndex); } else if (sParameterInfo != null) { writer.WriteUInt16((ushort)sParameterInfo.Position); } else { throw new NotSupportedException(); } break; default: throw new NotSupportedException(); } } }
internal static void WriteConstant(BlobBuilder writer, object value) { if (value == null) { // The encoding of Type for the nullref value for FieldInit is ELEMENT_TYPE_CLASS with a Value of a 32-bit. writer.WriteUInt32(0); return; } var type = value.GetType(); if (type.GetTypeInfo().IsEnum) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { writer.WriteBoolean((bool)value); } else if (type == typeof(int)) { writer.WriteInt32((int)value); } else if (type == typeof(string)) { writer.WriteUTF16((string)value); } else if (type == typeof(byte)) { writer.WriteByte((byte)value); } else if (type == typeof(char)) { writer.WriteUInt16((char)value); } else if (type == typeof(double)) { writer.WriteDouble((double)value); } else if (type == typeof(short)) { writer.WriteInt16((short)value); } else if (type == typeof(long)) { writer.WriteInt64((long)value); } else if (type == typeof(sbyte)) { writer.WriteSByte((sbyte)value); } else if (type == typeof(float)) { writer.WriteSingle((float)value); } else if (type == typeof(ushort)) { writer.WriteUInt16((ushort)value); } else if (type == typeof(uint)) { writer.WriteUInt32((uint)value); } else if (type == typeof(ulong)) { writer.WriteUInt64((ulong)value); } else { // TODO: message throw new ArgumentException(); } }
internal static void WriteConstant(BlobBuilder writer, object value) { if (value == null) { // The encoding of Type for the nullref value for FieldInit is ELEMENT_TYPE_CLASS with a Value of a 32-bit. writer.WriteUInt32(0); return; } var type = value.GetType(); if (type.GetTypeInfo().IsEnum) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { writer.WriteBoolean((bool)value); } else if (type == typeof(int)) { writer.WriteInt32((int)value); } else if (type == typeof(string)) { writer.WriteUTF16((string)value); } else if (type == typeof(byte)) { writer.WriteByte((byte)value); } else if (type == typeof(char)) { writer.WriteUInt16((char)value); } else if (type == typeof(double)) { writer.WriteDouble((double)value); } else if (type == typeof(short)) { writer.WriteInt16((short)value); } else if (type == typeof(long)) { writer.WriteInt64((long)value); } else if (type == typeof(sbyte)) { writer.WriteSByte((sbyte)value); } else if (type == typeof(float)) { writer.WriteSingle((float)value); } else if (type == typeof(ushort)) { writer.WriteUInt16((ushort)value); } else if (type == typeof(uint)) { writer.WriteUInt32((uint)value); } else if (type == typeof(ulong)) { writer.WriteUInt64((ulong)value); } else { // TODO: message throw new ArgumentException(); } }