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 119 120 121 122 123 124 125 126
use std::io::{Read,Seek,SeekFrom}; use nom::IResult; use nom::number::complete::le_u32; use nom::bytes::complete::{tag,take}; use nom::sequence::tuple; use nom::multi::count; use nom::combinator::all_consuming; use chrono::naive::{NaiveDateTime,NaiveDate,NaiveTime}; use crate::{Decode,Error}; use crate::shared::decode_bytes_as_utf8_string; use crate::Entry; use super::{Wad,WadHeader,WadEntry}; impl Decode for Wad { fn decode<Source>(source: &mut Source) -> Result<Self, Error> where Source: Read + Seek { let mut header_buf = [0; 32]; let mut entries_buf = Vec::new(); source.read_exact(&mut header_buf)?; let (_, header) = all_consuming(Wad::decode_header)(&header_buf)?; source.seek(SeekFrom::Start(header.entries_offset as u64))?; source.read_to_end(&mut entries_buf)?; let (_, entries) = count(Wad::decode_entry, header.entries_count as usize)(&entries_buf)?; Ok(Wad { header: header, entries: entries }) } } impl Wad { pub fn decode_header(input: &[u8]) -> IResult<&[u8], WadHeader, Error> { let (input, _magic_number) = tag("BBBB")(input)?; let (input, version) = tuple((le_u32, le_u32, le_u32))(input)?; let (input, block_size) = le_u32(input)?; let (input, entries_count) = le_u32(input)?; let (input, _entries_count_again) = le_u32(input)?; let (input, entries_offset) = le_u32(input)?; Ok( ( input, WadHeader { version: version, block_size: block_size, entries_count: entries_count, entries_offset: entries_offset, } ) ) } pub fn decode_entry(input: &[u8]) -> IResult<&[u8], WadEntry, Error> { let (input, _unknown_1) = take(16usize)(input)?; let (input, id) = le_u32(input)?; let (input, _unknown_2) = le_u32(input)?; let (input, length) = le_u32(input)?; let (input, offset) = le_u32(input)?; let (input, _unknown_3) = le_u32(input)?; let (input, path_length) = le_u32(input)?; let (input, path) = take(path_length as usize)(input)?; let (_, path) = decode_bytes_as_utf8_string(path)?; let (input, _unknown_4) = take(16usize)(input)?; let (input, created) = Self::decode_timestamp(input)?; let (input, accessed) = Self::decode_timestamp(input)?; let (input, written) = Self::decode_short_timestamp(input)?; Ok( ( input, WadEntry { id: id, length: length, offset: offset, path: path, created: created, accessed: accessed, written: written, } ) ) } pub fn decode_timestamp(input: &[u8]) -> IResult<&[u8], NaiveDateTime, Error> { let (input, year) = le_u32(input)?; let (input, month) = le_u32(input)?; let (input, day) = le_u32(input)?; let (input, hour) = le_u32(input)?; let (input, minute) = le_u32(input)?; let (input, second) = le_u32(input)?; let (input, millisecond) = le_u32(input)?; let ymd = NaiveDate::from_ymd(year as i32, month, day); let hms = NaiveTime::from_hms_milli(hour, minute, second, millisecond); let date_time = NaiveDateTime::new(ymd, hms); Ok((input, date_time)) } pub fn decode_short_timestamp(input: &[u8]) -> IResult<&[u8], NaiveDateTime, Error> { let (input, year) = le_u32(input)?; let (input, month) = le_u32(input)?; let (input, day) = le_u32(input)?; let (input, hour) = le_u32(input)?; let (input, minute) = le_u32(input)?; let ymd = NaiveDate::from_ymd(year as i32, month, day); let hms = NaiveTime::from_hms(hour, minute, 0); let date_time = NaiveDateTime::new(ymd, hms); Ok((input, date_time)) } } impl Entry for WadEntry { fn len(&self) -> u64 { self.length as u64 } fn pos(&self) -> u64 { self.offset as u64 } }