@@ -2,130 +2,69 @@ use std::str;
22use petgraph:: prelude:: * ;
33use fnv:: FnvHashMap ;
44use crate :: MIME ;
5+ use nom:: {
6+ IResult ,
7+ bytes:: complete:: { is_not, tag, take, take_while} ,
8+ character:: is_digit,
9+ combinator:: { map, map_res, opt} ,
10+ multi:: many0,
11+ number:: complete:: be_u16,
12+ sequence:: { delimited, preceded, terminated, tuple} ,
13+ } ;
514
6- // Below functions from https://github.com/badboy/iso8601/blob/master/src/helper.rs
7- // but modified to be safe and provide defaults
8- pub fn to_string ( s : & [ u8 ] ) -> std:: result:: Result < & str , std:: str:: Utf8Error > {
9- str:: from_utf8 ( s)
10- }
11- pub fn to_u32 ( s : std:: result:: Result < & str , std:: str:: Utf8Error > , def : u32 ) -> u32 {
12-
13- match s {
14- Ok ( t) => { str:: FromStr :: from_str ( t) . unwrap_or ( def) } ,
15- Err ( _) => def
16- }
17- }
18-
19- pub fn buf_to_u32 ( s : & [ u8 ] , def : u32 ) -> u32 {
20- to_u32 ( to_string ( s) , def)
21- }
22-
23- // Initial mime string
24- // Format: [priority: mime]
25- named ! ( mime<& str >,
26- map_res!(
27- delimited!(
28- delimited!(
29- char !( '[' ) ,
30- is_not!( ":" ) ,
31- char !( ':' )
32- ) ,
33- is_not!( "]" ) , // the mime
34- tag!( "]\n " )
35- ) ,
36- str :: from_utf8
37- )
38- ) ;
15+ // Singular magic ruleset
16+ fn magic_rules ( input : & [ u8 ] ) -> IResult < & [ u8 ] , super :: MagicRule > {
17+ let int_or = |default| map (
18+ take_while ( is_digit) ,
19+ move |digits| str:: from_utf8 ( digits) . unwrap ( ) . parse ( ) . unwrap_or ( default)
20+ ) ;
3921
40- // Indent levels sub-parser for magic_rules
41- // Default value 0
42- named ! ( magic_rules_indent_level<u32 >,
43- do_parse!(
44- ret: take_until!( ">" ) >>
45- ( buf_to_u32( ret, 0 ) )
46- )
47- ) ;
22+ let ( input, ( indent_level, start_off, val_len) ) = tuple ( (
23+ terminated ( int_or ( 0 ) , tag ( ">" ) ) ,
24+ terminated ( int_or ( 0 ) , tag ( "=" ) ) ,
25+ be_u16,
26+ ) ) ( input) ?;
4827
49- // Start offset sub-parser for magic_rules
50- named ! ( magic_rules_start_off<u32 >,
51- do_parse!(
52- ret: take_until!( "=" ) >>
53- ( buf_to_u32( ret, 0 ) )
54- )
55- ) ;
28+ let ( input, ( val, mask, word_len, region_len) ) = terminated (
29+ tuple ( (
30+ take ( val_len) ,
31+ opt ( preceded ( tag ( "&" ) , take ( val_len) ) ) ,
32+ opt ( preceded ( tag ( "~" ) , int_or ( 1 ) ) ) ,
33+ opt ( preceded ( tag ( "+" ) , int_or ( 0 ) ) ) ,
34+ ) ) ,
35+ tag ( "\n " )
36+ ) ( input) ?;
5637
57- // Singular magic ruleset
58- named ! ( magic_rules<super :: MagicRule >,
59- do_parse!(
60- peek!( is_a!( "012345689>" ) ) >>
61- _indent_level: magic_rules_indent_level >>
62- tag!( ">" ) >>
63- _start_off: magic_rules_start_off >>
64- tag!( "=" ) >>
65- _val_len: u16 !( nom:: Endianness :: Big ) >> // length of value
66- _val: do_parse!(
67- ret: take!( _val_len) >>
68- ( ret. iter( ) . map( |& x| x) . collect( ) )
69- ) >> // value
70-
71- _mask: opt!(
72- do_parse!(
73- char !( '&' ) >>
74- ret: take!( _val_len) >> // mask (default 0xFF)
75- ( ret. iter( ) . map( |& x| x) . collect( ) )
76- )
77- ) >>
78-
79- // word size (default 1)
80- _word_len: opt!(
81- do_parse!(
82- tag!( "~" ) >>
83- ret: take_until!( "+" ) >>
84- ( buf_to_u32( ret, 1 ) )
85- )
86- ) >>
87-
88- // length of region in file to check (default 1)
89- _region_len: opt!(
90- do_parse!(
91- tag!( "+" ) >>
92- ret: take_until!( "\n " ) >>
93- ( buf_to_u32( ret, 0 ) )
94- )
95- ) >>
96-
97- take_until_and_consume!( "\n " ) >>
98-
99- ( super :: MagicRule {
100- indent_level: _indent_level,
101- start_off: _start_off,
102- val: _val,
103- val_len: _val_len,
104- mask: _mask,
105- word_len: _word_len. unwrap_or( 1 ) ,
106- region_len: _region_len. unwrap_or( 0 )
107- } )
108- )
109-
110- ) ;
111-
112- /// Singular magic entry
113- named ! ( magic_entry<( MIME , Vec <super :: MagicRule >) >,
114- do_parse!(
115- _mime: do_parse!( ret: mime >> ( ret. to_string( ) ) ) >>
116- _rules: many0!( magic_rules) >> ( _mime, _rules)
117- )
118- ) ;
38+ Ok ( ( input, super :: MagicRule {
39+ indent_level,
40+ start_off,
41+ val : val. to_vec ( ) ,
42+ val_len,
43+ mask : mask. map ( Vec :: from) ,
44+ word_len : word_len. unwrap_or ( 1 ) ,
45+ region_len : region_len. unwrap_or ( 0 ) ,
46+ } ) )
47+ }
11948
12049/// Converts a magic file given as a &[u8] array
12150/// to a vector of MagicEntry structs
122- named ! ( from_u8_to_tuple_vec<Vec <( MIME , Vec <super :: MagicRule >) >>,
123- do_parse!(
124- tag!( "MIME-Magic\0 \n " ) >>
125- ret: many0!( magic_entry) >>
126- ( ret)
127- )
128- ) ;
51+ fn ruleset ( input : & [ u8 ] ) -> IResult < & [ u8 ] , Vec < ( MIME , Vec < super :: MagicRule > ) > > {
52+ // Parse the MIME type from "[priority: mime]"
53+ let mime = map ( map_res (
54+ terminated (
55+ delimited (
56+ delimited ( tag ( "[" ) , is_not ( ":" ) , tag ( ":" ) ) , // priority
57+ is_not ( "]" ) , // mime
58+ tag ( "]" )
59+ ) ,
60+ tag ( "\n " ) ,
61+ ) ,
62+ str:: from_utf8) ,
63+ str:: to_string) ;
64+
65+ let magic_entry = tuple ( ( mime, many0 ( magic_rules) ) ) ;
66+ preceded ( tag ( "MIME-Magic\0 \n " ) , many0 ( magic_entry) ) ( input)
67+ }
12968
13069fn gen_graph ( magic_rules : Vec < super :: MagicRule > ) -> DiGraph < super :: MagicRule , u32 >
13170{
@@ -159,15 +98,9 @@ fn gen_graph(magic_rules: Vec<super::MagicRule>) -> DiGraph<super::MagicRule, u3
15998}
16099
161100pub fn from_u8 ( b : & [ u8 ] ) -> Result < FnvHashMap < MIME , DiGraph < super :: MagicRule , u32 > > , String > {
162- let tuplevec = from_u8_to_tuple_vec ( b) . to_result ( ) . map_err ( |e| e. to_string ( ) ) ?;
163- let mut res = FnvHashMap :: < MIME , DiGraph < super :: MagicRule , u32 > > :: default ( ) ;
164-
165- for x in tuplevec {
166- res. insert ( x. 0 , gen_graph ( x. 1 ) ) ;
167- }
168-
101+ let tuplevec = ruleset ( b) . map_err ( |e| e. to_string ( ) ) ?. 1 ;
102+ let res = tuplevec. into_iter ( ) . map ( |x| ( x. 0 , gen_graph ( x. 1 ) ) ) . collect ( ) ;
169103 Ok ( res)
170-
171104}
172105
173106/// Loads the given magic file and outputs a vector of MagicEntry structs
0 commit comments