internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, ByteReader br) { this.lazyConstructor = constructor; if (br.Length == 0) { // it's legal to have an empty blob lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array; lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array; } else { if (br.ReadUInt16() != 1) { throw new BadImageFormatException(); } lazyConstructorArguments = ReadConstructorArguments(asm, br, constructor); lazyNamedArguments = ReadNamedArguments(asm, br, br.ReadUInt16(), constructor.DeclaringType); } }
void ReadFixedArg(StringBuilder sb, ByteReader br, Type type, bool arrayElement = false) { if (type.IsArray) { int length = br.ReadInt32(); if (length == -1 && compat == CompatLevel.None) { sb.Append("nullref"); } else if (length == 0 && compat != CompatLevel.None) { throw new IKVM.Reflection.BadImageFormatException(); } else { Type elementType = type.GetElementType(); AppendCATypeName(sb, elementType, null); sb.AppendFormat("[{0}](", length); for (int i = 0; i < length; i++) { if (i != 0) { sb.Append(' '); } if (elementType == typeofSystemObject) { string typeName; ReadFixedArg(sb, br, ReadFieldOrPropType(sb, br, out typeName), false); } else { ReadFixedArg(sb, br, elementType, true); } } sb.Append(')'); } } else if (type.FullName == "System.Type" && type.Assembly.GetName().Name == "mscorlib") { if (!arrayElement) { AppendCATypeName(sb, type, null); sb.Append('('); } string typeName; var type1 = ReadType(br, out typeName); if (type1 == null) { if (typeName == null) { sb.Append("nullref"); } else { sb.Append("class ").Append(QuoteIdentifier(typeName, true)); } } else { AppendTypeName(sb, type1, typeName, compat != CompatLevel.None && IsNestedTypeWithNamespace(type1)); } if (!arrayElement) { sb.Append(')'); } } else if (type.Assembly == mscorlib) { if (!arrayElement) { AppendCATypeName(sb, type, null); sb.Append('('); } if (type == typeofSystemBoolean) { sb.Append(br.ReadByte() == 0 ? "false" : "true"); } else if (type == typeofSystemByte) { sb.Append(br.ReadByte()); } else if (type == typeofSystemSByte) { sb.Append(br.ReadSByte()); } else if (type == typeofSystemChar) { sb.AppendFormat("0x{0:X4}", (int)br.ReadChar()); } else if (type == typeofSystemInt16) { sb.Append(br.ReadInt16()); } else if (type == typeofSystemUInt16) { sb.Append(br.ReadUInt16()); } else if (type == typeofSystemInt32) { sb.Append(br.ReadInt32()); } else if (type == typeofSystemUInt32) { sb.Append(br.ReadInt32()); } else if (type == typeofSystemInt64) { sb.Append(br.ReadInt64()); } else if (type == typeofSystemUInt64) { sb.Append(br.ReadInt64()); } else if (type == typeofSystemSingle) { sb.Append(ToString(br.ReadSingle(), true)); } else if (type == typeofSystemDouble) { sb.Append(ToString(br.ReadDouble(), true)); } else if (type == typeofSystemString) { var str = br.ReadString(); if (str == null) { sb.Append("nullref"); } else { if (compat != CompatLevel.None) { int pos = str.IndexOf((char)0); if (pos != -1) { str = str.Substring(0, pos); } } sb.Append(QuoteIdentifier(str, true)); } } else if (type == typeofSystemObject) { string typeName; ReadFixedArg(sb, br, ReadFieldOrPropType(sb, br, out typeName)); } else { throw new NotImplementedException(type.FullName); } if (!arrayElement) { sb.Append(')'); } } else if (type.__IsMissing || (compat != CompatLevel.None && typerefs.Contains(type))) { // ildasm actually tries to load the assembly, but we can't do that, so we cheat by having // a list of 'known' enum types if (type.Assembly.GetName().Name == "mscorlib") { switch (type.FullName) { case "System.AttributeTargets": case "System.Runtime.ConstrainedExecution.Consistency": case "System.Runtime.ConstrainedExecution.Cer": case "System.Security.Permissions.SecurityAction": case "System.Security.Permissions.SecurityPermissionFlag": case "System.Runtime.Versioning.ResourceScope": case "System.Runtime.InteropServices.CallingConvention": case "System.Runtime.InteropServices.CharSet": ReadFixedArg(sb, br, typeofSystemInt32); return; case "System.Security.SecurityRuleSet": if (compat != CompatLevel.V20) { ReadFixedArg(sb, br, typeofSystemByte); return; } break; case "System.Diagnostics.Tracing.EventLevel": case "System.Diagnostics.Tracing.EventTask": case "System.Diagnostics.Tracing.EventOpcode": if (compat != CompatLevel.V20 && compat != CompatLevel.V40) { ReadFixedArg(sb, br, typeofSystemInt32); return; } break; case "System.Type": sb.Append("type("); string typeName; AppendTypeName(sb, ReadType(br, out typeName), typeName); sb.Append(")"); return; } } switch (br.Length) { case 1: if (compat != CompatLevel.None) { // ildasm uses bool (???) as the underlying type in this case sb.AppendFormat("bool({0})", br.ReadByte() == 0 ? "false" : "true"); } else { // just guess that the enum has int8 as the underlying type sb.AppendFormat("int8({0})", br.ReadSByte()); } break; case 2: // just guess that the enum has int16 as the underlying type sb.AppendFormat("int16({0})", br.ReadInt16()); break; case 4: // just guess that the enum has int32 as the underlying type sb.AppendFormat("int32({0})", br.ReadInt32()); break; case 8: // just guess that the enum has int64 as the underlying type sb.AppendFormat("int64({0})", br.ReadInt64()); break; default: throw new IKVM.Reflection.BadImageFormatException(); } } else if (type.IsEnum) { ReadFixedArg(sb, br, type.GetEnumUnderlyingType(), arrayElement); } else { throw new NotImplementedException(type.FullName); } }
bool DecodeCABlob(StringBuilder sb, ConstructorInfo constructor, byte[] blob, int level) { try { // CustomAttribute var br = new ByteReader(blob, 2, blob.Length - 4); ReadConstructorArguments(sb, br, constructor, level); br = new ByteReader(blob, blob.Length - (br.Length + 2), br.Length + 2); int named = br.ReadUInt16(); if (constructor.GetParameters().Length != 0 && named != 0) { AppendNewLine(sb, level); } ReadNamedArguments(sb, br, named, level, false); return true; } catch (IKVM.Reflection.BadImageFormatException) { } catch (ArgumentOutOfRangeException) { } return false; }
private static OrdinalOrName ReadOrdinalOrName(ByteReader br) { char c = br.ReadChar(); if (c == 0xFFFF) { return new OrdinalOrName(br.ReadUInt16()); } else { StringBuilder sb = new StringBuilder(); while (c != 0) { sb.Append(c); c = br.ReadChar(); } return new OrdinalOrName(sb.ToString()); } }
internal RESOURCEHEADER(ByteReader br) { DataSize = br.ReadInt32(); HeaderSize = br.ReadInt32(); TYPE = ReadOrdinalOrName(br); NAME = ReadOrdinalOrName(br); br.Align(4); DataVersion = br.ReadInt32(); MemoryFlags = br.ReadUInt16(); LanguageId = br.ReadUInt16(); Version = br.ReadInt32(); Characteristics = br.ReadInt32(); }
private static CustomAttributeTypedArgument ReadFixedArg(Module context, ByteReader br, Type type) { Universe u = context.universe; if (type == u.System_String) { return new CustomAttributeTypedArgument(type, br.ReadString()); } else if (type == u.System_Boolean) { return new CustomAttributeTypedArgument(type, br.ReadByte() != 0); } else if (type == u.System_Char) { return new CustomAttributeTypedArgument(type, br.ReadChar()); } else if (type == u.System_Single) { return new CustomAttributeTypedArgument(type, br.ReadSingle()); } else if (type == u.System_Double) { return new CustomAttributeTypedArgument(type, br.ReadDouble()); } else if (type == u.System_SByte) { return new CustomAttributeTypedArgument(type, br.ReadSByte()); } else if (type == u.System_Int16) { return new CustomAttributeTypedArgument(type, br.ReadInt16()); } else if (type == u.System_Int32) { return new CustomAttributeTypedArgument(type, br.ReadInt32()); } else if (type == u.System_Int64) { return new CustomAttributeTypedArgument(type, br.ReadInt64()); } else if (type == u.System_Byte) { return new CustomAttributeTypedArgument(type, br.ReadByte()); } else if (type == u.System_UInt16) { return new CustomAttributeTypedArgument(type, br.ReadUInt16()); } else if (type == u.System_UInt32) { return new CustomAttributeTypedArgument(type, br.ReadUInt32()); } else if (type == u.System_UInt64) { return new CustomAttributeTypedArgument(type, br.ReadUInt64()); } else if (type == u.System_Type) { return new CustomAttributeTypedArgument(type, ReadType(context, br)); } else if (type == u.System_Object) { return ReadFixedArg(context, br, ReadFieldOrPropType(context, br)); } else if (type.IsArray) { int length = br.ReadInt32(); if (length == -1) { return new CustomAttributeTypedArgument(type, null); } Type elementType = type.GetElementType(); CustomAttributeTypedArgument[] array = new CustomAttributeTypedArgument[length]; for (int i = 0; i < length; i++) { array[i] = ReadFixedArg(context, br, elementType); } return new CustomAttributeTypedArgument(type, array); } else if (type.IsEnum) { return new CustomAttributeTypedArgument(type, ReadFixedArg(context, br, type.GetEnumUnderlyingTypeImpl()).Value); } else { throw new InvalidOperationException(); } }
private static CustomAttributeTypedArgument ReadFixedArg(Assembly asm, ByteReader br, Type type) { Universe u = asm.universe; if (type == u.System_String) { return new CustomAttributeTypedArgument(type, br.ReadString()); } else if (type == u.System_Type) { return new CustomAttributeTypedArgument(type, ReadType(asm, br)); } else if (type == u.System_Object) { return ReadFixedArg(asm, br, ReadFieldOrPropType(asm, br)); } else if (type.IsArray) { int length = br.ReadInt32(); if (length == -1) { return new CustomAttributeTypedArgument(type, null); } Type elementType = type.GetElementType(); CustomAttributeTypedArgument[] array = new CustomAttributeTypedArgument[length]; for (int i = 0; i < length; i++) { array[i] = ReadFixedArg(asm, br, elementType); } return new CustomAttributeTypedArgument(type, array); } else if (type.IsEnum) { return new CustomAttributeTypedArgument(type, ReadFixedArg(asm, br, type.GetEnumUnderlyingTypeImpl()).Value); } else { switch (Type.GetTypeCode(type)) { case TypeCode.Boolean: return new CustomAttributeTypedArgument(type, br.ReadByte() != 0); case TypeCode.Char: return new CustomAttributeTypedArgument(type, br.ReadChar()); case TypeCode.Single: return new CustomAttributeTypedArgument(type, br.ReadSingle()); case TypeCode.Double: return new CustomAttributeTypedArgument(type, br.ReadDouble()); case TypeCode.SByte: return new CustomAttributeTypedArgument(type, br.ReadSByte()); case TypeCode.Int16: return new CustomAttributeTypedArgument(type, br.ReadInt16()); case TypeCode.Int32: return new CustomAttributeTypedArgument(type, br.ReadInt32()); case TypeCode.Int64: return new CustomAttributeTypedArgument(type, br.ReadInt64()); case TypeCode.Byte: return new CustomAttributeTypedArgument(type, br.ReadByte()); case TypeCode.UInt16: return new CustomAttributeTypedArgument(type, br.ReadUInt16()); case TypeCode.UInt32: return new CustomAttributeTypedArgument(type, br.ReadUInt32()); case TypeCode.UInt64: return new CustomAttributeTypedArgument(type, br.ReadUInt64()); default: throw new InvalidOperationException(); } } }