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
use std::fmt;
use nom::{
bytes::streaming::take,
combinator::{map, rest},
number::complete::be_u16,
sequence::tuple,
IResult,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Date(pub u16);
impl fmt::Display for Date {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let year = (self.0 >> 9) + 1980;
let month = (self.0 >> 5) & 0b1111;
let day = self.0 & 0b11111;
write!(f, "{:02}.{:02}.{:04}", day, month, year)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Time(pub u16);
impl fmt::Display for Time {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let hours = self.0 >> 11;
let minutes = (self.0 >> 5) & 0b111111;
let seconds = (self.0 & 0b11111) << 1;
write!(f, "{:02}:{:02}:{:02}", hours, minutes, seconds)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct DateTime {
pub date: Date,
pub time: Time,
}
impl fmt::Display for DateTime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {}", self.date, self.time)
}
}
#[derive(Debug)]
pub struct Header<'a> {
pub lead: &'a [u8],
pub ctime: DateTime,
pub mtime: DateTime,
pub trail: &'a [u8],
}
pub fn p_time(input: &[u8]) -> IResult<&[u8], Time> {
map(be_u16, Time)(input)
}
pub fn p_date(input: &[u8]) -> IResult<&[u8], Date> {
map(be_u16, Date)(input)
}
pub fn p_datetime(input: &[u8]) -> IResult<&[u8], DateTime> {
map(tuple((p_date, p_time)), |(date, time)| DateTime {
date,
time,
})(input)
}
pub fn parse_header(input: &[u8]) -> IResult<&[u8], Header> {
let (rest, (lead, ctime, mtime, trail)) =
tuple((take(0x48usize), p_datetime, p_datetime, rest))(input)?;
Ok((
rest,
Header {
lead,
ctime,
mtime,
trail,
},
))
}