예제 #1
0
        private void Parse(CLRSignatureParser parser, CLRSigType elemType)
        {
            ElementType = elemType.BasicType;

            switch (elemType.BasicType)
            {
                case CLRSigType.ElementType.BOOLEAN:
                    Value = (parser.ReadU8() != 0);
                    break;
                case CLRSigType.ElementType.CHAR:
                    Value = (char)(parser.ReadU16());
                    break;
                case CLRSigType.ElementType.R4:
                    Value = parser.ReadF32();
                    break;
                case CLRSigType.ElementType.R8:
                    Value = parser.ReadF64();
                    break;
                case CLRSigType.ElementType.I1:
                    Value = parser.ReadS8();
                    break;
                case CLRSigType.ElementType.U1:
                    Value = parser.ReadU8();
                    break;
                case CLRSigType.ElementType.I2:
                    Value = parser.ReadS16();
                    break;
                case CLRSigType.ElementType.U2:
                    Value = parser.ReadU16();
                    break;
                case CLRSigType.ElementType.I4:
                    Value = parser.ReadS32();
                    break;
                case CLRSigType.ElementType.U4:
                    Value = parser.ReadU32();
                    break;
                case CLRSigType.ElementType.I8:
                    Value = parser.ReadS64();
                    break;
                case CLRSigType.ElementType.U8:
                    Value = parser.ReadU64();
                    break;
                case CLRSigType.ElementType.STRING:
                    Value = ReadUTF8String(parser);
                    break;
                case CLRSigType.ElementType.OBJECT:
                    Parse(parser, ReadFieldOrPropType(parser));
                    return;
                case CLRSigType.ElementType.CLASS:
                case CLRSigType.ElementType.VALUETYPE:
                    {
                        CLRSigTypeStructured st = (CLRSigTypeStructured)elemType;
                        CLRTableRow underlyingType = st.TypeDefOrRefOrSpec;
                        string typeNamespace, typeName;
                        if (underlyingType is CLRTypeDefRow)
                        {
                            CLRTypeDefRow typeDef = (CLRTypeDefRow)underlyingType;
                            typeNamespace = typeDef.TypeNamespace;
                            typeName = typeDef.TypeName;
                        }
                        else if (underlyingType is CLRTypeRefRow)
                        {
                            CLRTypeRefRow typeRef = (CLRTypeRefRow)underlyingType;
                            typeNamespace = typeRef.TypeNamespace;
                            typeName = typeRef.TypeName;
                        }
                        else
                            throw new ParseFailedException("Unusual CA type");

                        if (typeNamespace == "System" && typeName == "Type")
                        {
                            Parse(parser, new CLRSigTypeSimple(CLRSigType.ElementType.STRING));
                            return;
                        }

                        // Must be an enum
                        {
                            CLRTypeDefRow enumType;

                            if (underlyingType is CLRTypeDefRow)
                                enumType = (CLRTypeDefRow)underlyingType;
                            else if (underlyingType is CLRTypeRefRow)
                            {
                                CLRTypeRefRow typeRef = (CLRTypeRefRow)underlyingType;
                                if (typeRef.Resolution == null)
                                    throw new ParseFailedException("Custom attribute references unresolved enum type");
                                enumType = typeRef.Resolution;
                            }
                            else
                                throw new ParseFailedException("Unexpected CA underlying type");

                            CLRSigType valueType = null;

                            foreach (CLRFieldRow field in enumType.Fields)
                            {
                                if (!field.Static)
                                {
                                    valueType = field.Signature.Type;
                                    break;
                                }
                            }

                            if (valueType == null)
                                throw new ParseFailedException("Unknown CA enum type");
                            Parse(parser, valueType);
                        }
                    }
                    break;
                default:
                    throw new NotSupportedException("Unsupported custom attrib type");
            }
        }