Ildasm.Disassembler.ReadFixedArg C# (CSharp) Method

ReadFixedArg() static private method

static private ReadFixedArg ( System.StringBuilder sb, ByteReader br, Managed.Reflection.Type type, bool arrayElement = false ) : void
sb System.StringBuilder
br ByteReader
type Managed.Reflection.Type
arrayElement bool
return void
        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 Managed.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 Managed.Reflection.BadImageFormatException();
                }
            }
            else if (type.IsEnum)
            {
                ReadFixedArg(sb, br, type.GetEnumUnderlyingType(), arrayElement);
            }
            else
            {
                throw new NotImplementedException(type.FullName);
            }
        }