use std::io::ErrorKind;
use binrw::{BinRead, BinReaderExt};
use encoding_rs::Encoding;
use getset::Getters;
#[allow(unused)]
use log::{debug, error, info, trace, warn};
#[cfg(feature = "serde")]
use serde::Serialize;
use self::{
console_data::ConsoleDataBlock, console_fe_data::ConsoleFEDataBlock,
darwin_data::DarwinDataBlock, environment_variable_data::EnvironmentVariableDataBlock,
icon_environment_data::IconEnvironmentDataBlock, known_folder_data::KnownFolderDataBlock,
property_store_data::PropertyStoreDataBlock, shell_item_identifiers::ShellItemIdentifiers,
shim_data::ShimDataBlock, special_folder_data::SpecialFolderDataBlock,
tracker_data::TrackerDataBlock, vista_and_above_id_list_data::VistaAndAboveIdListDataBlock,
};
pub mod console_data;
pub mod console_fe_data;
pub mod darwin_data;
pub mod environment_variable_data;
pub mod icon_environment_data;
pub mod known_folder_data;
pub mod property_store_data;
pub mod shim_data;
pub mod special_folder_data;
pub mod tracker_data;
pub mod vista_and_above_id_list_data;
pub mod shell_item_identifiers;
#[allow(missing_docs)]
#[derive(Clone, Debug, BinRead)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[br(import(_block_size: u32, _default_codepage: &'static Encoding))]
pub enum ExtraDataBlock {
#[br(magic = 0xa0000001u32)]
EnvironmentProps(#[br(args(_block_size, _default_codepage))] EnvironmentVariableDataBlock),
#[br(magic = 0xa0000002u32)]
ConsoleProps(#[br(args(_block_size))] ConsoleDataBlock),
#[br(magic = 0xa0000003u32)]
TrackerProps(#[br(args(_block_size, _default_codepage))] TrackerDataBlock),
#[br(magic = 0xa0000004u32)]
ConsoleFeProps(#[br(args(_block_size))] ConsoleFEDataBlock),
#[br(magic = 0xa0000005u32)]
SpecialFolderProps(#[br(args(_block_size))] SpecialFolderDataBlock),
#[br(magic = 0xa0000006u32)]
DarwinProps(#[br(args(_block_size, _default_codepage))] DarwinDataBlock),
#[br(magic = 0xa0000007u32)]
IconEnvironmentProps(#[br(args(_block_size, _default_codepage))] IconEnvironmentDataBlock),
#[br(magic = 0xa0000008u32)]
ShimProps(#[br(args(_block_size))] ShimDataBlock),
#[br(magic = 0xa0000009u32)]
PropertyStoreProps(#[br(args(_block_size))] PropertyStoreDataBlock),
#[br(magic = 0xa000000au32)]
VistaAndAboveIdListProps(#[br(args(_block_size))] VistaAndAboveIdListDataBlock),
#[br(magic = 0xa000000bu32)]
KnownFolderProps(#[br(args(_block_size))] KnownFolderDataBlock),
#[br(magic = 0xa000000cu32)]
ShellItemIdentifiers(#[br(args(_block_size))] ShellItemIdentifiers),
}
#[derive(Default, Debug, Getters)]
#[allow(missing_docs, unused)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[getset(get = "pub")]
pub struct ExtraData {
blocks: Vec<ExtraDataBlock>,
}
impl BinRead for ExtraData {
type Args<'a> = (&'static Encoding,);
fn read_options<R: std::io::Read + std::io::Seek>(
reader: &mut R,
_endian: binrw::Endian,
args: Self::Args<'_>,
) -> binrw::BinResult<Self> {
let mut blocks = Vec::new();
loop {
let block_size: u32 = match reader.read_le() {
Ok(block_size) => block_size,
Err(binrw::Error::Io(why)) => {
if why.kind() == ErrorKind::UnexpectedEof {
break;
} else {
return Err(binrw::Error::Io(why));
}
}
Err(why) => return Err(why),
};
if block_size == 0 {
break;
} else {
let block: ExtraDataBlock = reader.read_le_args((block_size, args.0))?;
blocks.push(block);
}
}
Ok(Self { blocks })
}
}