abxml/chunks/
chunk_header.rs

1use std::fmt;
2
3#[derive(Clone, Copy, Debug)]
4pub struct ChunkHeader {
5    offset: u64,
6    header_size: u16,
7    chunk_size: u32,
8    chunk_type: u16,
9}
10
11impl ChunkHeader {
12    pub fn new(offset: u64, header_size: u16, chunk_size: u32, chunk_type: u16) -> Self {
13        Self {
14            offset,
15            header_size,
16            chunk_size,
17            chunk_type,
18        }
19    }
20
21    pub fn get_offset(&self) -> u64 {
22        self.offset
23    }
24
25    pub fn get_header_size(&self) -> u16 {
26        self.header_size
27    }
28
29    pub fn get_data_offset(&self) -> u64 {
30        self.offset + u64::from(self.header_size)
31    }
32
33    pub fn get_chunk_end(&self) -> u64 {
34        self.offset + u64::from(self.chunk_size)
35    }
36
37    pub fn absolute(&self, relative: u64) -> u64 {
38        let absolute = self.offset + relative;
39
40        if absolute > self.get_chunk_end() {
41            panic!("Requested a relative value out of bounds");
42        }
43
44        absolute
45    }
46
47    pub fn get_token(&self) -> u16 {
48        self.chunk_type
49    }
50}
51
52impl fmt::Display for ChunkHeader {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        write!(
55            f,
56            "(Token:{:X}; Start: {}; Data: {}; End {})",
57            self.chunk_type,
58            self.offset,
59            self.get_data_offset(),
60            self.get_chunk_end()
61        )
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::ChunkHeader;
68
69    #[test]
70    pub fn it_returns_data_offset() {
71        let chunk = ChunkHeader::new(4000, 8, 16, 0);
72
73        assert_eq!(4008, chunk.get_data_offset());
74    }
75
76    #[test]
77    pub fn it_returns_chunk_end() {
78        let chunk = ChunkHeader::new(4000, 8, 16, 0);
79
80        assert_eq!(4016, chunk.get_chunk_end());
81    }
82
83    #[test]
84    #[should_panic]
85    pub fn it_panics_from_relative_out_of_bound() {
86        let chunk = ChunkHeader::new(4000, 8, 500, 0);
87        chunk.absolute(510);
88    }
89
90    #[test]
91    pub fn it_returns_absolute_offsets_from_relative_ones() {
92        let chunk = ChunkHeader::new(4000, 8, 500, 0);
93        let res = chunk.absolute(490);
94
95        assert_eq!(4490, res);
96    }
97}