abxml/chunks/
chunk_header.rs1use 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}