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"); } }