use byteorder::{ByteOrder, LittleEndian};
use crate::section::SectionCore;
#[derive(Clone, Debug)]
pub struct GenericSection<'a> {
core_len: usize,
data: &'a[u8],
}
impl GenericSection<'_> {
#[warn(deprecated)]
pub fn bytes(&self) -> &[u8] { &self.data }
pub fn from_slice(slice: &[u8]) -> Result<GenericSection, crate::error::Errors> {
if slice.len() == 0 {
return Err(crate::error::Errors::NoData);
}
match slice[0] {
1 | 2 => GenericSection::buffer_to_generic(&slice, 5, 2, 15), 17 => GenericSection::buffer_to_generic(&slice, 5, 1, 12),
32 => GenericSection::buffer_to_generic(&slice, 4, 1, 12),
33 => GenericSection::buffer_to_generic(&slice, 5, 2, 12),
49 | 50 => GenericSection::buffer_to_generic(&slice, 5, 1, 9),
81 => GenericSection::buffer_to_generic(&slice, 5, 1, 10),
113 => GenericSection::buffer_to_generic(&slice, 5, 1, 7),
129 | 130 => GenericSection::buffer_to_generic(&slice, 2, 2, 12),
145 | 146 | 147 => GenericSection::buffer_to_generic(&slice, 2, 1, 9),
149 => GenericSection::buffer_to_generic(&slice, 4, 1, 13),
161 | 162 => GenericSection::buffer_to_generic(&slice, 2, 2, 9),
177 | 178 | 179 => GenericSection::buffer_to_generic(&slice, 2, 1, 6),
193 => GenericSection::buffer_to_generic(&slice, 2, 2, 10),
209 => GenericSection::buffer_to_generic(&slice, 2, 1, 7),
225 | 226 => GenericSection::buffer_to_generic(&slice, 2, 2, 7),
241 | 242 => GenericSection::buffer_to_generic(&slice, 2, 1, 4),
_ => Err(crate::error::Errors::InvalidBuffer),
}
}
fn buffer_to_generic(slice: &[u8], size_offset: usize, size_len: usize, core_size: usize) -> Result<GenericSection, crate::error::Errors> {
if slice.len() < core_size {
eprintln!("Failed due to insufficient slice length for core ({} of {} expected)", slice.len(), core_size);
return Err(crate::error::Errors::BufferTooSmall);
}
let data_len = match size_len {
0 => 0,
1 => slice[size_offset] as usize,
2 => LittleEndian::read_u16(&slice[size_offset..]) as usize,
_ => panic!("Unsupported size length: {}", size_len),
};
if slice.len() < core_size + data_len {
eprintln!("Failed due to insufficient slice length for data ({} of {} + {} expected)", slice.len(), core_size, data_len);
return Err(crate::error::Errors::BufferTooSmall);
}
Ok(GenericSection {
core_len: core_size,
data: &slice[0..core_size+data_len],
})
}
}
impl SectionCore for GenericSection<'_> {
const KIND: u8 = 0;
fn kind(&self) -> u8 {self.data[0]}
fn core_len(&self) -> usize { self.core_len }
fn data_len(&self) -> usize { self.data.len()-self.core_len }
fn raw_data(&self) -> std::option::Option<&[u8]> { if self.data_len() == 0 { None } else {Some(&self.data[self.core_len..])} }
}