@@ -2,130 +2,69 @@ use std::str;
2
2
use petgraph:: prelude:: * ;
3
3
use fnv:: FnvHashMap ;
4
4
use 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
+ } ;
5
14
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
+ ) ;
39
21
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) ?;
48
27
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) ?;
56
37
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
+ }
119
48
120
49
/// Converts a magic file given as a &[u8] array
121
50
/// 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
+ }
129
68
130
69
fn gen_graph ( magic_rules : Vec < super :: MagicRule > ) -> DiGraph < super :: MagicRule , u32 >
131
70
{
@@ -159,15 +98,9 @@ fn gen_graph(magic_rules: Vec<super::MagicRule>) -> DiGraph<super::MagicRule, u3
159
98
}
160
99
161
100
pub 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 ( ) ;
169
103
Ok ( res)
170
-
171
104
}
172
105
173
106
/// Loads the given magic file and outputs a vector of MagicEntry structs
0 commit comments