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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
pub mod packet_type;
pub use packet_type::*;
pub mod pixel_config;
pub use pixel_config::{PixelConfig, PixelFormat};
pub mod id;
pub use id::ID;
pub mod message;
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct Header {
pub packet_type: PacketType,
pub sequence_number: u8,
pub pixel_config: PixelConfig,
pub id: ID,
pub offset: u32,
pub length: u16,
// TODO - Implement timecode
//pub timecode: u32,
}
impl Default for Header {
fn default() -> Self {
Self {
packet_type: Default::default(),
sequence_number: Default::default(),
pixel_config: Default::default(),
id: Default::default(),
offset: Default::default(),
length: Default::default(),
//timecode: 0,
}
}
}
impl Into<[u8; 10]> for Header {
fn into(self) -> [u8; 10] {
// Define a byte array with the size of the header
let mut buffer = [0u8; 10];
// Write the packet type field to the buffer
let packet_type_byte = self.packet_type.into();
buffer[0] = packet_type_byte;
// Write the sequence number field to the buffer
buffer[1] = self.sequence_number;
// Write the pixel config field to the buffer
buffer[2] = self.pixel_config.into();
// Write the id field to the buffer
buffer[3] = self.id.into();
// Write the offset field to the buffer
let offset_bytes = self.offset.to_be_bytes();
buffer[4..8].copy_from_slice(&offset_bytes);
// Write the length field to the buffer
let length_bytes = self.length.to_be_bytes();
buffer[8..10].copy_from_slice(&length_bytes);
// Return a slice of the buffer representing the entire header
buffer
}
}
impl<'a> From<&'a [u8]> for Header {
fn from(bytes: &'a [u8]) -> Self {
// Extract the packet type field from the buffer
let packet_type = PacketType::from(bytes[0]);
// Extract the sequence number field from the buffer
let sequence_number = bytes[1];
// Extract the pixel config field from the buffer
let pixel_config = PixelConfig::from(bytes[2]);
// Extract the id field from the buffer
let id = ID::from(bytes[3]);
// Extract the offset field from the buffer
let offset = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
// Extract the length field from the buffer
let length = u16::from_be_bytes([bytes[8], bytes[9]]);
Header {
packet_type,
sequence_number,
pixel_config,
id,
offset,
length,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parsing() {
// Normal
{
let data: [u8; 10] = [65, 6, 10, 1, 0, 0, 0, 0, 0, 3];
let header = Header::from(&data[..]);
assert_eq!(
header.packet_type,
PacketType {
version: 1,
timecode: false,
storage: false,
reply: false,
query: false,
push: true
}
);
assert_eq!(header.sequence_number, 6);
assert_eq!(header.length, 3);
assert_eq!(header.offset, 0);
}
// oddity
{
let data: [u8; 10] = [255, 12, 13, 1, 0, 0, 0x99, 0xd5, 0x01, 0x19];
let header = Header::from(&data[..]);
assert_eq!(
header.packet_type,
PacketType {
version: 3,
timecode: true,
storage: true,
reply: true,
query: true,
push: true
}
);
assert_eq!(header.sequence_number, 12);
assert_eq!(
header.pixel_config,
PixelConfig {
data_type: pixel_config::DataType::RGB,
data_size: PixelFormat::Pixel24Bits,
customer_defined: false
}
);
assert_eq!(header.length, 281);
assert_eq!(header.offset, 39381);
}
}
}