1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use nom::IResult;
use nom::{le_u64,le_u32,le_u16};
use block::RawBlock;
use options::{parse_options,Options};
pub const TY: u32 = 0x0A0D0D0A;
named!(section_header_body<&[u8],SectionHeader>,
chain!(
magic: le_u32 ~
major_version: le_u16 ~
minor_version: le_u16 ~
_section_length: le_u64 ~
options: parse_options?,
||{
let section_length = if _section_length == 0xFFFFFFFFFFFFFFFF {
SectionLength::Unspecified
} else {
SectionLength::Bytes(_section_length)
};
assert_eq!(magic, 0x1A2B3C4D);
SectionHeader {
ty: TY,
block_length: 0,
magic: magic,
major_version: major_version,
minor_version: minor_version,
section_length: section_length,
options: options,
check_length: 0,
} }
)
);
#[derive(PartialEq,Debug)]
pub enum SectionLength {
Bytes(u64),
Unspecified,
}
#[derive(Debug)]
pub struct SectionHeader<'a> {
pub ty: u32,
pub block_length: u32,
pub magic: u32,
pub major_version: u16,
pub minor_version: u16,
pub section_length: SectionLength,
pub options: Option<Options<'a>>,
pub check_length: u32,
}
pub fn parse(blk: RawBlock) -> SectionHeader {
match section_header_body(blk.body) {
IResult::Done(_, mut block) => {
block.block_length = blk.block_length;
block.check_length = blk.check_length;
block
},
_ => {
panic!("Couldn't unpack this section_header");
}
}
}
#[cfg(test)]
use block::parse_block;
#[test]
fn test_parse_section_header() {
let input = b"\n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1c\x00\x00\x00";
match parse_block(input) {
IResult::Done(left, block) => {
let section_header = parse(block);
assert_eq!(left, b"");
assert_eq!(section_header.ty, 0x0A0D0D0A);
assert_eq!(section_header.block_length, 28);
assert_eq!(section_header.magic, 0x1A2B3C4D);
assert_eq!(section_header.section_length, SectionLength::Unspecified);
assert!(section_header.options.is_none());
assert_eq!(section_header.check_length, 28);
},
_ => {
assert_eq!(1, 2);
},
}
}