use crate::utils::*;
use crate::{Class, Data, Version};
#[derive(Debug, Clone)]
pub enum ParseIdentError {
BrokenHeader,
BadPropertyMagic,
BadPropertyClass,
BadPropertyData,
BadPropertyVersion,
}
#[repr(C)]
#[derive(Debug, Clone)]
pub struct Ident {
pub magic: [u8; 4],
pub class: u8,
pub data: u8,
pub version: u8,
pub osabi: u8,
pub abiversion: u8,
pub reserved: [u8; 7],
}
impl Ident {
pub fn parse(data: &[u8]) -> Result<&Self, ParseIdentError> {
use ParseIdentError::*;
let ident: &Ident = read(data, 0).ok_or(BrokenHeader)?;
if ident.magic != [0x7F, b'E', b'L', b'F'] {
return Err(BadPropertyMagic);
}
let _class = ident.checked_class().ok_or(BadPropertyClass)?;
let _data = ident.checked_data().ok_or(BadPropertyData)?;
let _version = ident.checked_version().ok_or(BadPropertyVersion)?;
Ok(unsafe { &*(data.as_ptr() as *const Ident) })
}
pub fn as_bytes(&self) -> &[u8; 16] {
unsafe { core::mem::transmute(self) }
}
pub fn magic(&self) -> [u8; 4] {
self.magic
}
pub fn checked_class(&self) -> Option<Class> {
Class::try_from(self.class).ok()
}
pub fn class(&self) -> Class {
self.checked_class().unwrap()
}
pub fn checked_data(&self) -> Option<Data> {
Data::try_from(self.data).ok()
}
pub fn data(&self) -> Data {
self.checked_data().unwrap()
}
pub fn checked_version(&self) -> Option<Version> {
Version::try_from(self.version).ok()
}
pub fn version(&self) -> Version {
self.checked_version().unwrap()
}
pub fn os_abi(&self) -> u8 {
self.osabi
}
pub fn abi_version(&self) -> u8 {
self.abiversion
}
}
unsafe impl Pod for Ident {}
pub const IDENT_OSABI_NONE: u8 = 0;
pub const IDENT_OSABI_HPUX: u8 = 1;
pub const IDENT_OSABI_NETBSD: u8 = 2;
pub const IDENT_OSABI_GNU: u8 = 3;
pub const IDENT_OSABI_SOLARIS: u8 = 6;
pub const IDENT_OSABI_AIX: u8 = 7;
pub const IDENT_OSABI_IRIX: u8 = 8;
pub const IDENT_OSABI_FREEBSD: u8 = 9;
pub const IDENT_OSABI_TRU64: u8 = 10;
pub const IDENT_OSABI_MODESTRO: u8 = 11;
pub const IDENT_OSABI_OPENBSD: u8 = 12;
pub const IDENT_OSABI_OPENVMS: u8 = 13;
pub const IDENT_OSABI_NSK: u8 = 14;
pub const IDENT_OSABI_AROS: u8 = 15;
pub const IDENT_OSABI_FENIXOS: u8 = 16;
pub const IDENT_OSABI_CLOUDABI: u8 = 17;
pub const IDENT_OSABI_OPENVOS: u8 = 18;