e57/
packet.rs

1use crate::error::{Converter, WRONG_OFFSET};
2use crate::{Error, Result};
3use std::io::{Read, Write};
4
5pub enum PacketHeader {
6    Index(IndexPacketHeader),
7    Data(DataPacketHeader),
8    Ignored(IgnoredPacketHeader),
9}
10
11impl PacketHeader {
12    pub fn read(reader: &mut dyn Read) -> Result<Self> {
13        // Read only first byte of header to indetify packet type
14        let mut buffer = [0_u8; 1];
15        reader
16            .read_exact(&mut buffer)
17            .read_err("Failed to read packet type ID")?;
18
19        if buffer[0] == IndexPacketHeader::ID {
20            Ok(PacketHeader::Index(IndexPacketHeader::read(reader)?))
21        } else if buffer[0] == DataPacketHeader::ID {
22            Ok(PacketHeader::Data(DataPacketHeader::read(reader)?))
23        } else if buffer[0] == IgnoredPacketHeader::ID {
24            Ok(PacketHeader::Ignored(IgnoredPacketHeader::read(reader)?))
25        } else {
26            Error::invalid("Found unknown packet ID when trying to read packet header")?
27        }
28    }
29}
30
31pub struct IndexPacketHeader {
32    pub packet_length: u64,
33}
34
35impl IndexPacketHeader {
36    pub const ID: u8 = 0;
37
38    pub fn read(reader: &mut dyn Read) -> Result<Self> {
39        let mut buffer = [0_u8; 15];
40        reader
41            .read_exact(&mut buffer)
42            .read_err("Failed to read index packet header")?;
43
44        // Check reserved values in second and last eight bytes of header
45        if buffer[0] != 0 {
46            Error::invalid("The reserved bytes inside an index packet must be zero")?
47        }
48        for value in buffer.iter().skip(7) {
49            if *value != 0 {
50                Error::invalid("The reserved bytes inside an index packet must be zero")?
51            }
52        }
53
54        // Parse values
55        let packet_length =
56            u16::from_le_bytes(buffer[1..3].try_into().internal_err(WRONG_OFFSET)?) as u64 + 1;
57
58        // Currently unused header fields
59        let _entry_count = u16::from_le_bytes(buffer[3..5].try_into().internal_err(WRONG_OFFSET)?);
60        let _index_level = buffer[5];
61
62        // Validate length
63        if packet_length % 4 != 0 {
64            Error::invalid("Index packet length is not aligned and a multiple of four")?
65        }
66
67        Ok(Self { packet_length })
68    }
69}
70
71pub struct DataPacketHeader {
72    pub comp_restart_flag: bool,
73    pub packet_length: u64,
74    pub bytestream_count: u16,
75}
76
77impl DataPacketHeader {
78    pub const ID: u8 = 1;
79
80    pub const SIZE: usize = 6;
81
82    pub fn read(reader: &mut dyn Read) -> Result<Self> {
83        let mut buffer = [0_u8; 5];
84        reader
85            .read_exact(&mut buffer)
86            .read_err("Failed to read data packet header")?;
87
88        // Parse values
89        let comp_restart_flag = buffer[0] & 1 != 0;
90        let packet_length =
91            u16::from_le_bytes(buffer[1..3].try_into().internal_err(WRONG_OFFSET)?) as u64 + 1;
92        let bytestream_count =
93            u16::from_le_bytes(buffer[3..5].try_into().internal_err(WRONG_OFFSET)?);
94
95        // Validate values
96        if packet_length % 4 != 0 {
97            Error::invalid("Data packet length is not aligned and a multiple of four")?
98        }
99        if bytestream_count == 0 {
100            Error::invalid("A byte stream count of 0 is not allowed")?
101        }
102
103        Ok(Self {
104            comp_restart_flag,
105            packet_length,
106            bytestream_count,
107        })
108    }
109
110    pub fn write(&self, writer: &mut dyn Write) -> Result<()> {
111        let mut buffer = [0_u8; Self::SIZE];
112        buffer[0] = 1;
113        let flags = if self.comp_restart_flag { 1_u8 } else { 0_u8 };
114        buffer[1] = flags;
115        let length = (self.packet_length - 1) as u16;
116        buffer[2..4].copy_from_slice(&length.to_le_bytes());
117        buffer[4..6].copy_from_slice(&self.bytestream_count.to_le_bytes());
118        writer
119            .write_all(&buffer)
120            .write_err("Failed to write data packet header")
121    }
122}
123
124pub struct IgnoredPacketHeader {
125    pub packet_length: u64,
126}
127
128impl IgnoredPacketHeader {
129    pub const ID: u8 = 2;
130
131    pub fn read(reader: &mut dyn Read) -> Result<Self> {
132        // Read Ignored Packet
133        let mut buffer = [0_u8; 3];
134        reader
135            .read_exact(&mut buffer)
136            .read_err("Failed to read ignore packet header")?;
137
138        // Check reserved value
139        if buffer[0] != 0 {
140            Error::invalid("The first byte inside ignored packets is reserved and must be zero")?
141        }
142
143        // Parse length
144        let packet_length =
145            u16::from_le_bytes(buffer[1..3].try_into().internal_err(WRONG_OFFSET)?) as u64 + 1;
146
147        // Validate length
148        if packet_length % 4 != 0 {
149            Error::invalid("Ignored packet length is not aligned and a multiple of four")?
150        }
151
152        Ok(Self { packet_length })
153    }
154}