use nom::{number::streaming::be_u8, Err, IResult, Needed};
use crate::Error;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Trailer {
pub calibrated_time_enable: bool,
pub valid_data_enable: bool,
pub reference_lock_enable: bool,
pub agcmgc_enable: bool,
pub detected_signal_enable: bool,
pub spectral_inversion_enable: bool,
pub overrange_enable: bool,
pub sample_loss_enable: bool,
pub user_defined_enable_1: bool,
pub user_defined_enable_2: bool,
pub user_defined_enable_3: bool,
pub user_defined_enable_4: bool,
pub calibrated_time_indicator: bool,
pub valid_data_indicator: bool,
pub reference_lock_indicator: bool,
pub agcmgc_indicator: bool,
pub detected_signal_indicator: bool,
pub spectral_inversion_indicator: bool,
pub overrange_indicator: bool,
pub sample_loss_indicator: bool,
pub user_defined_indicator_1: bool,
pub user_defined_indicator_2: bool,
pub user_defined_indicator_3: bool,
pub user_defined_indicator_4: bool,
pub associated_context_packet_count_enable: bool,
pub associated_context_packet_count: u8,
}
impl Trailer {
pub fn parse(i: &[u8]) -> IResult<&[u8], Trailer> {
if i.len() < 4 {
return Err(Err::Incomplete(Needed::new(4)));
}
let (i, first_byte) = be_u8(i)?;
let (i, second_byte) = be_u8(i)?;
let (i, third_byte) = be_u8(i)?;
let (i, fourth_byte) = be_u8(i)?;
let calibrated_time_enable: u8 = (first_byte >> 7) & 0x01;
let valid_data_enable: u8 = (first_byte >> 6) & 0x01;
let reference_lock_enable: u8 = (first_byte >> 5) & 0x01;
let agcmgc_enable: u8 = (first_byte >> 4) & 0x01;
let detected_signal_enable: u8 = (first_byte >> 3) & 0x01;
let spectral_inversion_enable: u8 = (first_byte >> 2) & 0x01;
let overrange_enable: u8 = (first_byte >> 1) & 0x01;
let sample_loss_enable: u8 = (first_byte) & 0x01;
let user_defined_enable_1: u8 = (second_byte >> 7) & 0x01;
let user_defined_enable_2: u8 = (second_byte >> 6) & 0x01;
let user_defined_enable_3: u8 = (second_byte >> 5) & 0x01;
let user_defined_enable_4: u8 = (second_byte >> 4) & 0x01;
let calibrated_time_indicator: u8 = (second_byte >> 3) & 0x01;
let valid_data_indicator: u8 = (second_byte >> 2) & 0x01;
let reference_lock_indicator: u8 = (second_byte >> 1) & 0x01;
let agcmgc_indicator: u8 = (second_byte) & 0x01;
let detected_signal_indicator: u8 = (third_byte >> 7) & 0x01;
let spectral_inversion_indicator: u8 = (third_byte >> 6) & 0x01;
let overrange_indicator: u8 = (third_byte >> 5) & 0x01;
let sample_loss_indicator: u8 = (third_byte >> 4) & 0x01;
let user_defined_indicator_1: u8 = (third_byte >> 3) & 0x01;
let user_defined_indicator_2: u8 = (third_byte >> 2) & 0x01;
let user_defined_indicator_3: u8 = (third_byte >> 1) & 0x01;
let user_defined_indicator_4: u8 = (third_byte) & 0x01;
let associated_context_packet_count_enable: u8 = (fourth_byte >> 7) & 0x01;
let associated_context_packet_count_value: u8 = (fourth_byte) & 0x7f;
let hdr: Trailer = Trailer {
calibrated_time_enable: calibrated_time_enable != 0,
valid_data_enable: valid_data_enable != 0,
reference_lock_enable: reference_lock_enable != 0,
agcmgc_enable: agcmgc_enable != 0,
detected_signal_enable: detected_signal_enable != 0,
spectral_inversion_enable: spectral_inversion_enable != 0,
overrange_enable: overrange_enable != 0,
sample_loss_enable: sample_loss_enable != 0,
user_defined_enable_1: user_defined_enable_1 != 0,
user_defined_enable_2: user_defined_enable_2 != 0,
user_defined_enable_3: user_defined_enable_3 != 0,
user_defined_enable_4: user_defined_enable_4 != 0,
calibrated_time_indicator: calibrated_time_indicator != 0,
valid_data_indicator: valid_data_indicator != 0,
reference_lock_indicator: reference_lock_indicator != 0,
agcmgc_indicator: agcmgc_indicator != 0,
detected_signal_indicator: detected_signal_indicator != 0,
spectral_inversion_indicator: spectral_inversion_indicator != 0,
overrange_indicator: overrange_indicator != 0,
sample_loss_indicator: sample_loss_indicator != 0,
user_defined_indicator_1: user_defined_indicator_1 != 0,
user_defined_indicator_2: user_defined_indicator_2 != 0,
user_defined_indicator_3: user_defined_indicator_3 != 0,
user_defined_indicator_4: user_defined_indicator_4 != 0,
associated_context_packet_count_enable: associated_context_packet_count_enable != 0,
associated_context_packet_count: associated_context_packet_count_value,
};
Ok((i, hdr))
}
pub fn serialize(&self, buffer: &mut [u8]) -> Result<usize, Error> {
if buffer.len() < 4 {
return Err(Error::BufferFull);
}
let mut word = 0;
word |= u32::from(self.calibrated_time_enable) << 31;
word |= u32::from(self.valid_data_enable) << 30;
word |= u32::from(self.reference_lock_enable) << 29;
word |= u32::from(self.agcmgc_enable) << 28;
word |= u32::from(self.detected_signal_enable) << 27;
word |= u32::from(self.spectral_inversion_enable) << 26;
word |= u32::from(self.overrange_enable) << 25;
word |= u32::from(self.sample_loss_enable) << 24;
word |= u32::from(self.user_defined_enable_1) << 23;
word |= u32::from(self.user_defined_enable_2) << 22;
word |= u32::from(self.user_defined_enable_3) << 21;
word |= u32::from(self.user_defined_enable_4) << 20;
word |= u32::from(self.calibrated_time_indicator) << 19;
word |= u32::from(self.calibrated_time_indicator) << 18;
word |= u32::from(self.reference_lock_indicator) << 17;
word |= u32::from(self.agcmgc_indicator) << 16;
word |= u32::from(self.detected_signal_indicator) << 15;
word |= u32::from(self.spectral_inversion_indicator) << 14;
word |= u32::from(self.overrange_indicator) << 13;
word |= u32::from(self.sample_loss_indicator) << 12;
word |= u32::from(self.user_defined_indicator_1) << 11;
word |= u32::from(self.user_defined_indicator_2) << 10;
word |= u32::from(self.user_defined_indicator_3) << 9;
word |= u32::from(self.user_defined_indicator_4) << 8;
word |= u32::from(self.associated_context_packet_count_enable) << 7;
word |= u32::from(self.associated_context_packet_count) & 0x7f;
buffer.copy_from_slice(&word.to_be_bytes());
Ok(4)
}
}