use super::{CharSpec, DescriptorTag, EntityIdentifier, LongAllocationDescriptor, TagIdentifier};
use crate::error::Result;
use crate::time::UdfTimestamp;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FileSetDescriptor {
pub tag: DescriptorTag,
pub recording_date_time: UdfTimestamp,
pub interchange_level: u16,
pub max_interchange_level: u16,
pub character_set_list: u32,
pub max_character_set_list: u32,
pub file_set_number: u32,
pub file_set_desc_number: u32,
pub logical_volume_id_char_set: CharSpec,
pub logical_volume_identifier: [u8; 128],
pub file_set_char_set: CharSpec,
pub file_set_identifier: [u8; 32],
pub copyright_file_identifier: [u8; 32],
pub abstract_file_identifier: [u8; 32],
pub root_directory_icb: LongAllocationDescriptor,
pub domain_identifier: EntityIdentifier,
pub next_extent: LongAllocationDescriptor,
pub system_stream_directory_icb: LongAllocationDescriptor,
reserved: [u8; 32],
}
unsafe impl bytemuck::Zeroable for FileSetDescriptor {}
unsafe impl bytemuck::Pod for FileSetDescriptor {}
impl FileSetDescriptor {
#[cfg(feature = "alloc")]
pub(crate) fn into_native(mut self) -> Self {
self.tag = DescriptorTag::from_disk_bytes(bytemuck::bytes_of(&self.tag))
.expect("DescriptorTag has its fixed on-disk size");
self.recording_date_time = self.recording_date_time.into_native();
self.interchange_level = self.interchange_level.to_le();
self.max_interchange_level = self.max_interchange_level.to_le();
self.character_set_list = self.character_set_list.to_le();
self.max_character_set_list = self.max_character_set_list.to_le();
self.file_set_number = self.file_set_number.to_le();
self.file_set_desc_number = self.file_set_desc_number.to_le();
self.root_directory_icb = self.root_directory_icb.into_native();
self.next_extent = self.next_extent.into_native();
self.system_stream_directory_icb = self.system_stream_directory_icb.into_native();
self
}
pub fn validate(&self, location: u32) -> Result<()> {
self.tag
.validate(TagIdentifier::FileSetDescriptor, location)
}
pub fn root_icb(&self) -> &LongAllocationDescriptor {
&self.root_directory_icb
}
#[cfg(feature = "alloc")]
pub fn file_set_id(&self) -> alloc::string::String {
super::primary::decode_dstring(&self.file_set_identifier)
}
pub fn is_udf_domain(&self) -> bool {
self.domain_identifier.is(b"*OSTA UDF Compliant")
}
}
#[cfg(test)]
mod tests {
use super::*;
static_assertions::const_assert_eq!(size_of::<FileSetDescriptor>(), 512);
}