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
use std::convert::TryInto;
use crate::{common::parser::parse_crc_node, md5::MD5Sum};
use super::file::*;
use nom::{
bytes::complete::{tag, take},
combinator::{map, map_res},
multi::length_count,
number::complete::le_u32,
sequence::tuple,
IResult,
};
pub fn parse_pk_magic(input: &[u8]) -> IResult<&[u8], ()> {
let (rest, _) = tag("ndpk")(input)?;
Ok((rest, ()))
}
pub fn parse_pk_trailer(input: &[u8]) -> IResult<&[u8], PKTrailer> {
map(tuple((le_u32, le_u32)), |(a, b)| PKTrailer {
file_list_base_addr: a,
value_1: b,
})(input)
}
fn parse_hash(i: &[u8]) -> IResult<&[u8], MD5Sum> {
map_res(take(32usize), MD5Sum::from_hex_bytes)(i)
}
fn parse_compressed(i: &[u8]) -> IResult<&[u8], u32> {
let (i, byte_slice) = take(4usize)(i)?;
let bytes: [u8; 4] = byte_slice.try_into().unwrap();
Ok((i, u32::from_le_bytes(bytes)))
}
pub fn parse_pk_entry_data(input: &[u8]) -> IResult<&[u8], PKEntryData> {
let (input, orig_file_size) = le_u32(input)?;
let (input, orig_file_hash) = parse_hash(input)?;
let (input, _ofh_padding) = take(4usize)(input)?;
let (input, compr_file_size) = le_u32(input)?;
let (input, compr_file_hash) = parse_hash(input)?;
let (input, _cfh_padding) = take(4usize)(input)?;
let (input, file_data_addr) = le_u32(input)?;
let (input, is_compressed) = parse_compressed(input)?;
Ok((
input,
PKEntryData {
orig_file_size,
orig_file_hash,
compr_file_size,
compr_file_hash,
file_data_addr,
is_compressed,
},
))
}
pub fn parse_pk_entry(input: &[u8]) -> IResult<&[u8], PKEntry> {
parse_crc_node(parse_pk_entry_data)(input)
}
pub fn parse_pk_entry_list(input: &[u8]) -> IResult<&[u8], Vec<PKEntry>> {
length_count(le_u32, parse_pk_entry)(input)
}