classfile_parser/
parser.rs1use nom::*;
2
3use attribute_info::attribute_parser;
4use constant_info::constant_parser;
5use field_info::field_parser;
6use method_info::method_parser;
7use nom::bytes::complete::tag;
8use nom::multi::count;
9use types::{ClassAccessFlags, ClassFile};
10
11fn magic_parser(input: &[u8]) -> IResult<&[u8], &[u8]> {
12 tag(&[0xCA, 0xFE, 0xBA, 0xBE])(input)
13}
14
15pub fn class_parser(input: &[u8]) -> IResult<&[u8], ClassFile> {
32 use nom::number::complete::be_u16;
33 let (input, _) = magic_parser(input)?;
34 let (input, minor_version) = be_u16(input)?;
35 let (input, major_version) = be_u16(input)?;
36 let (input, const_pool_size) = be_u16(input)?;
37 let (input, const_pool) = constant_parser(input, (const_pool_size - 1) as usize)?;
38 let (input, access_flags) = be_u16(input)?;
39 let (input, this_class) = be_u16(input)?;
40 let (input, super_class) = be_u16(input)?;
41 let (input, interfaces_count) = be_u16(input)?;
42 let (input, interfaces) = count(be_u16, interfaces_count as usize)(input)?;
43 let (input, fields_count) = be_u16(input)?;
44 let (input, fields) = count(field_parser, fields_count as usize)(input)?;
45 let (input, methods_count) = be_u16(input)?;
46 let (input, methods) = count(method_parser, methods_count as usize)(input)?;
47 let (input, attributes_count) = be_u16(input)?;
48 let (input, attributes) = count(attribute_parser, attributes_count as usize)(input)?;
49 Ok((
50 input,
51 ClassFile {
52 minor_version,
53 major_version,
54 const_pool_size,
55 const_pool,
56 access_flags: ClassAccessFlags::from_bits_truncate(access_flags),
57 this_class,
58 super_class,
59 interfaces_count,
60 interfaces,
61 fields_count,
62 fields,
63 methods_count,
64 methods,
65 attributes_count,
66 attributes,
67 },
68 ))
69}