pub mod dataitems;
pub mod datatypes;
use custom_error::custom_error;
use crate::asterix::message::AsterixMessageParseError;
custom_error!{pub DataTypeError
InvalidDataTypeConversion{type_name: String} = "It was provided an invalid data type for conversion for attribute {type_name}",
}
fn find_repetitive_len(len_octets: &[u8]) -> Result<usize, AsterixMessageParseError> {
if len_octets.len() > 2 {
return Err(AsterixMessageParseError::InvalidRepetitiveFieldLength { size: len_octets.len() })
}
let mut len_octets_array: [u8; 2] = [0, 0];
if len_octets.len() == 1 {
len_octets_array[1] = len_octets[0];
} else {
len_octets_array[0] = len_octets[0];
len_octets_array[1] = len_octets[1];
}
let len = u16::from_be_bytes(len_octets_array);
Ok(len as usize)
}
macro_rules! get_extensible_data_item_length {
($octets:expr, $start_index:expr) => {
{
use bitvec::prelude::*;
let mut len :usize = 1;
let mut current_index = $start_index;
let mut octet = $octets[current_index];
loop {
let octet_bits = octet.view_bits::<Lsb0>().to_bitvec();
let is_fx_set = octet_bits[0];
if is_fx_set {
len = len + 1;
current_index = current_index + 1;
octet = $octets[current_index];
} else {
break;
}
}
Ok(len)
}
}
}
macro_rules! get_repetitive_data_item_length {
($octets:expr, $start_index:expr, $attributes:expr) => {
{
let len: usize = $start_index + $attributes[0].octets_len as usize;
let len_octets = $octets[$start_index..len].iter().clone().as_slice();
let repetitive_factor = match common::find_repetitive_len(len_octets) {
Ok(s) => s,
Err(e) => return Err(e),
};
let mut repetitive_block_length = len_octets.len();
let mut variable_len = 0 as usize;
let mut last_field = 1 as u8;
for attribute in $attributes {
if attribute.field != last_field {
variable_len = variable_len + attribute.octets_len as usize;
last_field = attribute.field;
}
}
repetitive_block_length = repetitive_block_length + (variable_len * repetitive_factor as usize);
Ok(repetitive_block_length)
} as Result<usize, AsterixMessageParseError>
}
}
pub(crate) use get_extensible_data_item_length;
pub(crate) use get_repetitive_data_item_length;