1pub use self::error::HeaderError;
4
5mod error;
6
7#[derive(Clone)]
9pub struct Header {
10 raw_blocksize: u8,
11 max_blocksize: u32,
12}
13
14impl Header {
15 pub fn parse(buf: [u8; 4]) -> Result<Self, HeaderError> {
17 let signature = &buf[..2];
18 if signature != b"BZ" {
19 return Err(HeaderError::InvalidSignature);
20 }
21
22 let version = buf[2];
23 if version != b'h' {
24 return Err(HeaderError::UnsupportedVersion);
25 }
26
27 let hundred_k_blocksize = buf[3];
28 match hundred_k_blocksize {
29 b'1'..=b'9' => {
30 let raw_blocksize = hundred_k_blocksize - b'0';
31 Self::from_raw_blocksize(raw_blocksize)
32 }
33 _ => Err(HeaderError::InvalidBlockSize),
34 }
35 }
36
37 pub fn from_raw_blocksize(raw_blocksize: u8) -> Result<Self, HeaderError> {
44 if raw_blocksize < 1 || raw_blocksize > 9 {
45 return Err(HeaderError::InvalidBlockSize);
46 }
47
48 let max_blocksize = 100 * 1000 * u32::from(raw_blocksize);
49 Ok(Self {
50 raw_blocksize,
51 max_blocksize,
52 })
53 }
54
55 pub fn raw_blocksize(&self) -> u8 {
59 self.raw_blocksize
60 }
61
62 pub fn max_blocksize(&self) -> u32 {
66 self.max_blocksize
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn valid_9k() {
76 let header = Header::parse(*b"BZh9").unwrap();
77 assert_eq!(header.raw_blocksize(), 9);
78 assert_eq!(header.max_blocksize(), 900000);
79 }
80}