use crate::stdf_codec::*;
use crate::stdf_error::{StdfError, StdfErrorKind};
use rust_stdf_derive::{stdf_match_expr, stdf_records};
use smart_default::SmartDefault;
mod type_0_file_info;
mod type_10_test_synopsis;
mod type_15_test_info;
mod type_180_reserved;
mod type_1_lot_info;
mod type_20_generic_data;
mod type_2_wafer_info;
mod type_50_program_segment;
mod type_5_part_info;
pub use type_0_file_info::*;
pub use type_10_test_synopsis::*;
pub use type_15_test_info::*;
pub use type_180_reserved::*;
pub use type_1_lot_info::*;
pub use type_20_generic_data::*;
pub use type_2_wafer_info::*;
pub use type_50_program_segment::*;
pub use type_5_part_info::*;
#[derive(SmartDefault, Debug, Clone, Copy, PartialEq, Eq)]
pub struct RecordHeader {
pub len: u16,
pub typ: u8,
pub sub: u8,
}
pub mod stdf_record_type {
use crate::stdf_error::{StdfError, StdfErrorKind};
use rust_stdf_derive::{stdf_match_expr, stdf_records};
stdf_records!(rec_codes);
#[inline(always)]
pub fn get_typ_sub_from_code(code: u64) -> Result<(u8, u8), StdfError> {
stdf_match_expr!(typ_sub_from_code)
}
#[inline(always)]
pub fn get_code_from_typ_sub(typ: u8, sub: u8) -> u64 {
stdf_match_expr!(code_from_typ_sub)
}
#[inline(always)]
pub fn get_rec_name_from_code(rec_type: u64) -> &'static str {
stdf_match_expr!(name_from_code)
}
#[inline(always)]
pub fn get_code_from_rec_name(rec_name: &str) -> u64 {
stdf_match_expr!(code_from_name)
}
}
stdf_records!(rec_enums);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RawDataElement {
pub offset: u64,
pub header: RecordHeader,
pub raw_data: Vec<u8>,
pub byte_order: ByteOrder,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RawDataElementView<'a> {
pub offset: u64,
pub header: RecordHeader,
pub raw_data: &'a [u8],
pub byte_order: ByteOrder,
}
impl RecordHeader {
#[inline(always)]
pub fn new() -> Self {
RecordHeader::default()
}
#[inline(always)]
pub fn read_from_bytes(
mut self,
raw_data: &[u8],
order: &ByteOrder,
) -> Result<Self, StdfError> {
match raw_data.len() {
0 => Err(StdfError::new(
StdfErrorKind::Eof,
String::from("No bytes to read"),
)),
1..=3 => Err(StdfError::new(
StdfErrorKind::UnexpectedEof,
String::from("Not enough data to construct record header"),
)),
_ => {
let len_bytes = [raw_data[0], raw_data[1]];
self.len = match order {
ByteOrder::LittleEndian => u16::from_le_bytes(len_bytes),
ByteOrder::BigEndian => u16::from_be_bytes(len_bytes),
};
self.typ = raw_data[2];
self.sub = raw_data[3];
Ok(self)
}
}
}
pub fn get_type(&self) -> u64 {
stdf_record_type::get_code_from_typ_sub(self.typ, self.sub)
}
}
impl StdfRecord {
#[inline(always)]
pub fn new(rec_type: u64) -> Self {
stdf_match_expr!(record_new)
}
#[inline(always)]
pub fn new_from_header(header: &RecordHeader) -> Self {
let code = stdf_record_type::get_code_from_typ_sub(header.typ, header.sub);
match code {
stdf_record_type::REC_RESERVE => {
let mut rec = ReservedRec::new();
rec.typ = header.typ;
rec.sub = header.sub;
StdfRecord::ReservedRec(rec)
}
stdf_record_type::REC_UNKNOWN => {
let mut rec = ReservedRec::new();
rec.typ = header.typ;
rec.sub = header.sub;
StdfRecord::UnknownRec(rec)
}
_ => StdfRecord::new(code),
}
}
#[inline(always)]
pub fn get_type(&self) -> u64 {
stdf_match_expr!(record_type)
}
#[inline(always)]
pub fn is_type(&self, rec_type: u64) -> bool {
(self.get_type() & rec_type) != 0
}
#[inline(always)]
pub fn read_from_bytes(&mut self, raw_data: &[u8], order: &ByteOrder) {
stdf_match_expr!(record_read)
}
#[inline(always)]
pub fn read_from_bytes_with_header(
raw_data: &[u8],
order: &ByteOrder,
) -> Result<StdfRecord, StdfError> {
let header = RecordHeader::new().read_from_bytes(raw_data, order)?;
let expected_end_pos = 4 + header.len as usize;
if raw_data.len() < expected_end_pos {
return Err(StdfError::new(
StdfErrorKind::UnexpectedEof,
format!(
"Length of stdf field data ({} - 4 = {}) is less than what header specified ({})",
raw_data.len(),
raw_data.len() - 4,
header.len
),
));
}
let data_slice = &raw_data[4..expected_end_pos];
let mut rec = StdfRecord::new_from_header(&header);
rec.read_from_bytes(data_slice, order);
Ok(rec)
}
}
impl<'a> StdfRecordView<'a> {
#[inline]
pub fn read_from_bytes(
header: RecordHeader,
raw_data: &'a [u8],
byte_order: &ByteOrder,
) -> Self {
stdf_match_expr!(view_read)
}
#[inline(always)]
pub fn read_from_bytes_with_header(
raw_data: &'a [u8],
order: &ByteOrder,
) -> Result<Self, StdfError> {
let header = RecordHeader::new().read_from_bytes(raw_data, order)?;
let expected_end_pos = 4 + header.len as usize;
if raw_data.len() < expected_end_pos {
return Err(StdfError::new(
StdfErrorKind::UnexpectedEof,
format!(
"Length of stdf field data ({} - 4 = {}) is less than what header specified ({})",
raw_data.len(),
raw_data.len() - 4,
header.len
),
));
}
let data_slice = &raw_data[4..expected_end_pos];
Ok(Self::read_from_bytes(header, data_slice, order))
}
#[inline(always)]
pub fn get_type(&self) -> u64 {
stdf_match_expr!(view_type)
}
#[inline(always)]
pub fn is_type(&self, rec_type: u64) -> bool {
(self.get_type() & rec_type) != 0
}
#[inline]
pub fn to_owned(&self) -> StdfRecord {
stdf_match_expr!(view_to_owned)
}
}
impl RawDataElement {
#[inline(always)]
pub fn is_type(&self, rec_type: u64) -> bool {
(self.header.get_type() & rec_type) != 0
}
}
impl From<&RawDataElement> for StdfRecord {
#[inline(always)]
fn from(raw_element: &RawDataElement) -> Self {
let mut rec = StdfRecord::new_from_header(&raw_element.header);
rec.read_from_bytes(&raw_element.raw_data, &raw_element.byte_order);
rec
}
}
impl<'a> From<&'a RawDataElement> for StdfRecordView<'a> {
#[inline]
fn from(raw_element: &'a RawDataElement) -> Self {
Self::read_from_bytes(
raw_element.header,
&raw_element.raw_data,
&raw_element.byte_order,
)
}
}
impl From<RawDataElement> for StdfRecord {
#[inline(always)]
fn from(raw_element: RawDataElement) -> Self {
let mut rec = StdfRecord::new_from_header(&raw_element.header);
rec.read_from_bytes(&raw_element.raw_data, &raw_element.byte_order);
rec
}
}
impl RawDataElementView<'_> {
#[inline(always)]
pub fn is_type(&self, rec_type: u64) -> bool {
(self.header.get_type() & rec_type) != 0
}
}
impl From<&RawDataElementView<'_>> for StdfRecord {
#[inline(always)]
fn from(raw_view: &RawDataElementView<'_>) -> Self {
let mut rec = StdfRecord::new_from_header(&raw_view.header);
rec.read_from_bytes(raw_view.raw_data, &raw_view.byte_order);
rec
}
}
impl<'a> From<&RawDataElementView<'a>> for StdfRecordView<'a> {
#[inline]
fn from(raw_view: &RawDataElementView<'a>) -> Self {
Self::read_from_bytes(raw_view.header, raw_view.raw_data, &raw_view.byte_order)
}
}
impl From<&RawDataElementView<'_>> for RawDataElement {
#[inline(always)]
fn from(raw_view: &RawDataElementView<'_>) -> Self {
RawDataElement {
offset: raw_view.offset,
header: raw_view.header,
raw_data: raw_view.raw_data.to_vec(),
byte_order: raw_view.byte_order,
}
}
}
impl<'a> From<&StdfRecordView<'a>> for StdfRecord {
#[inline(always)]
fn from(view: &StdfRecordView<'a>) -> Self {
view.to_owned()
}
}