@@ -8,7 +8,9 @@ use nom::{
88
99use java_constants:: ClassAccessFlags ;
1010
11- use crate :: { attribute:: AttributeInfo , constant_pool:: ConstantPoolItem , field:: FieldInfo , interface:: parse_interface, method:: MethodInfo } ;
11+ use crate :: {
12+ attribute:: AttributeInfo , constant_pool:: ConstantPoolItem , error:: ParseError , field:: FieldInfo , interface:: parse_interface, method:: MethodInfo ,
13+ } ;
1214
1315fn parse_this_class < ' a > ( data : & ' a [ u8 ] , constant_pool : & BTreeMap < u16 , ConstantPoolItem > ) -> IResult < & ' a [ u8 ] , Arc < String > > {
1416 let ( data, this_class) = be_u16 ( data) ?;
@@ -44,48 +46,56 @@ pub struct ClassInfo {
4446 pub attributes : Vec < AttributeInfo > ,
4547}
4648
47- impl ClassInfo {
48- fn parse_info ( data : & [ u8 ] ) -> IResult < & [ u8 ] , Self > {
49- let ( data, magic) = be_u32 ( data) ?;
50- if magic != 0xCAFEBABE {
51- return Err ( nom:: Err :: Error ( nom:: error:: Error :: new ( data, nom:: error:: ErrorKind :: Verify ) ) ) ;
52- }
49+ type ClassBody = (
50+ u16 ,
51+ Arc < String > ,
52+ Option < Arc < String > > ,
53+ Vec < Arc < String > > ,
54+ Vec < FieldInfo > ,
55+ Vec < MethodInfo > ,
56+ Vec < AttributeInfo > ,
57+ ) ;
5358
54- let ( data, minor_version) = be_u16 ( data) ?;
55- let ( data, major_version) = be_u16 ( data) ?;
56- let ( data, constant_pool) = ConstantPoolItem :: parse_all ( data) ?;
59+ impl ClassInfo {
60+ fn parse_body < ' a > ( data : & ' a [ u8 ] , constant_pool : & BTreeMap < u16 , ConstantPoolItem > ) -> IResult < & ' a [ u8 ] , ClassBody > {
5761 let ( data, access_flags) = be_u16 ( data) ?;
58- let ( data, this_class) = parse_this_class ( data, & constant_pool) ?;
59- let ( data, super_class) = parse_super_class ( data, & constant_pool) ?;
60- let ( data, interfaces) = length_count ( be_u16, |x| parse_interface ( x, & constant_pool) ) . parse ( data) ?;
61- let ( data, fields) = length_count ( be_u16, |x| FieldInfo :: parse ( x, & constant_pool) ) . parse ( data) ?;
62- let ( data, methods) = length_count ( be_u16, |x| MethodInfo :: parse ( x, & constant_pool) ) . parse ( data) ?;
63- let ( data, attributes) = length_count ( be_u16, |x| AttributeInfo :: parse ( x, & constant_pool) ) . parse ( data) ?;
62+ let ( data, this_class) = parse_this_class ( data, constant_pool) ?;
63+ let ( data, super_class) = parse_super_class ( data, constant_pool) ?;
64+ let ( data, interfaces) = length_count ( be_u16, |x| parse_interface ( x, constant_pool) ) . parse ( data) ?;
65+ let ( data, fields) = length_count ( be_u16, |x| FieldInfo :: parse ( x, constant_pool) ) . parse ( data) ?;
66+ let ( data, methods) = length_count ( be_u16, |x| MethodInfo :: parse ( x, constant_pool) ) . parse ( data) ?;
67+ let ( data, attributes) = length_count ( be_u16, |x| AttributeInfo :: parse ( x, constant_pool) ) . parse ( data) ?;
6468
65- Ok ( (
66- data,
67- Self {
68- magic,
69- minor_version,
70- major_version,
71- constant_pool,
72- access_flags : ClassAccessFlags :: from_bits_truncate ( access_flags) ,
73- this_class,
74- super_class,
75- interfaces,
76- fields,
77- methods,
78- attributes,
79- } ,
80- ) )
69+ Ok ( ( data, ( access_flags, this_class, super_class, interfaces, fields, methods, attributes) ) )
8170 }
8271
83- pub fn parse ( file : & [ u8 ] ) -> Option < Self > {
84- let ( remaining, result) = Self :: parse_info ( file) . ok ( ) ?;
72+ pub fn parse ( file : & [ u8 ] ) -> Result < Self , ParseError > {
73+ let ( data, magic) = be_u32 :: < _ , nom:: error:: Error < & [ u8 ] > > ( file) . map_err ( ParseError :: from_nom) ?;
74+ if magic != 0xCAFEBABE {
75+ return Err ( ParseError :: BadMagic ( magic) ) ;
76+ }
77+
78+ let ( data, minor_version) = be_u16 :: < _ , nom:: error:: Error < & [ u8 ] > > ( data) . map_err ( ParseError :: from_nom) ?;
79+ let ( data, major_version) = be_u16 :: < _ , nom:: error:: Error < & [ u8 ] > > ( data) . map_err ( ParseError :: from_nom) ?;
80+ let ( data, constant_pool) = ConstantPoolItem :: parse_all ( data) ?;
81+ let ( remaining, ( access_flags, this_class, super_class, interfaces, fields, methods, attributes) ) =
82+ Self :: parse_body ( data, & constant_pool) . map_err ( ParseError :: from_nom) ?;
8583 if !remaining. is_empty ( ) {
86- return None ;
84+ return Err ( ParseError :: TrailingData ) ;
8785 }
8886
89- Some ( result)
87+ Ok ( Self {
88+ magic,
89+ minor_version,
90+ major_version,
91+ constant_pool,
92+ access_flags : ClassAccessFlags :: from_bits_truncate ( access_flags) ,
93+ this_class,
94+ super_class,
95+ interfaces,
96+ fields,
97+ methods,
98+ attributes,
99+ } )
90100 }
91101}
0 commit comments