1use nom::{bytes::complete::tag, multi::count, number::complete::be_u16, IResult};
2
3use crate::attribute::parse_attributes;
4use crate::constant_pool::parse_constant_pool;
5use crate::field::parse_field;
6use crate::method::parse_method;
7use crate::types::*;
8
9pub fn parse_classfile(input: &[u8]) -> IResult<&[u8], ClassFile> {
14 let (input, _) = tag(&[0xCA, 0xFE, 0xBA, 0xBE])(input)?;
16
17 let (input, minor_version) = be_u16(input)?;
18 let (input, major_version) = be_u16(input)?;
19
20 let (input, constant_pool_count) = be_u16(input)?;
21 let (input, constant_pool) = parse_constant_pool(input, constant_pool_count)?;
22
23 let (input, access_flags) = be_u16(input)?;
24 let (input, this_class) = be_u16(input)?;
25 let (input, super_class) = be_u16(input)?;
26
27 let (input, interfaces_count) = be_u16(input)?;
28 let (input, interfaces) = count(be_u16, interfaces_count as usize)(input)?;
29
30 let (input, fields_count) = be_u16(input)?;
31 let (input, fields) = count(parse_field, fields_count as usize)(input)?;
32
33 let (input, methods_count) = be_u16(input)?;
34 let (input, methods) = count(parse_method, methods_count as usize)(input)?;
35
36 let (input, attributes) = parse_attributes(input)?;
37
38 Ok((
39 input,
40 ClassFile {
41 minor_version,
42 major_version,
43 constant_pool,
44 access_flags: ClassAccessFlags::from_bits_truncate(access_flags),
45 this_class,
46 super_class,
47 interfaces,
48 fields,
49 methods,
50 attributes,
51 },
52 ))
53}