예제 #1
0
        internal static AttributeNode ParseAttribute(Stream stream, ClassReaderState state, AttributeScope scope)
        {
            var attribute = new AttributeNode
            {
                Name = state.ConstantPool.GetEntry <Utf8Entry>(Binary.BigEndian.ReadUInt16(stream)).String
            };

            attribute.Parse(stream, scope, state);
            return(attribute);
        }
예제 #2
0
        private static MethodNode ParseMethod(Stream stream, ClassReaderState state)
        {
            var methodNode = new MethodNode
            {
                Owner = state.ClassNode,

                Access     = (MethodAccessModifiers)Binary.BigEndian.ReadUInt16(stream),
                Name       = state.ConstantPool.GetEntry <Utf8Entry>(Binary.BigEndian.ReadUInt16(stream)).String,
                Descriptor = MethodDescriptor.Parse(state.ConstantPool.GetEntry <Utf8Entry>(Binary.BigEndian.ReadUInt16(stream)).String)
            };
            var attributesCount = Binary.BigEndian.ReadUInt16(stream);

            methodNode.Attributes.Capacity = attributesCount;
            for (var i = 0; i < attributesCount; i++)
            {
                methodNode.Attributes.Add(ParseAttribute(stream, state, AttributeScope.Method));
            }
            return(methodNode);
        }
예제 #3
0
        public static ClassNode ParseClass(Stream stream)
        {
            var state  = new ClassReaderState();
            var result = new ClassNode();

            state.ClassNode = result;

            if (Binary.BigEndian.ReadUInt32(stream) != Magic)
            {
                throw new IOException("Wrong magic in class");
            }

            result.MinorVersion = Binary.BigEndian.ReadUInt16(stream);
            result.MajorVersion = (ClassVersion)Binary.BigEndian.ReadUInt16(stream);

            if (result.MajorVersion > ClassVersion.Java8)
            {
                throw new Exception($"Wrong Java version: {result.MajorVersion}");
            }

            var constantPool = new ConstantPool();

            constantPool.Read(stream);
            state.ConstantPool = constantPool;

            result.Access = (ClassAccessModifiers)Binary.BigEndian.ReadUInt16(stream);

            result.Name      = new ClassName(constantPool.GetEntry <ClassEntry>(Binary.BigEndian.ReadUInt16(stream)).Name.String);
            result.SuperName = new ClassName(constantPool.GetEntry <ClassEntry>(Binary.BigEndian.ReadUInt16(stream)).Name.String);

            var interfacesCount = Binary.BigEndian.ReadUInt16(stream);

            result.Interfaces.Capacity = interfacesCount;
            for (var i = 0; i < interfacesCount; i++)
            {
                result.Interfaces.Add(new ClassName(constantPool.GetEntry <ClassEntry>(Binary.BigEndian.ReadUInt16(stream)).Name.String));
            }

            var fieldsCount = Binary.BigEndian.ReadUInt16(stream);

            result.Fields.Capacity = fieldsCount;
            for (var i = 0; i < fieldsCount; i++)
            {
                result.Fields.Add(ParseField(stream, state));
            }

            var methodsCount = Binary.BigEndian.ReadUInt16(stream);

            result.Methods.Capacity = methodsCount;
            for (var i = 0; i < methodsCount; i++)
            {
                result.Methods.Add(ParseMethod(stream, state));
            }

            var attributesCount = Binary.BigEndian.ReadUInt16(stream);

            result.Attributes.Capacity = attributesCount;
            for (var i = 0; i < attributesCount; i++)
            {
                result.Attributes.Add(ParseAttribute(stream, state, AttributeScope.Class));
            }

            result.Parse(state);

            return(result);
        }