use crate::*;
use std::borrow::Borrow;
use std::convert::TryInto;
use std::fmt::{self, Debug, Formatter};
use std::ops::Deref;
#[repr(transparent)]
pub struct Bytecode([u8]);
impl Bytecode {
pub unsafe fn from(bytecode: &[u8]) -> Result<&Self, MethodError> {
if bytecode.get(0..=3) == Some(b"DXBC") {
let total_size = match bytecode.get(24..=27) {
Some(&[a,b,c,d]) => u32::from_le_bytes([a,b,c,d]),
_other => return Err(MethodError::new("Bytecode::from", THINERR::INVALID_BYTECODE)),
};
if bytecode.len() != total_size.try_into().map_err(|_| MethodError::new("Bytecode::from", THINERR::INVALID_BYTECODE))? {
return Err(MethodError::new("Bytecode::from", THINERR::INVALID_BYTECODE));
}
}
Ok(Self::from_unchecked(bytecode))
}
pub unsafe fn from_unchecked(bytecode: &[u8]) -> &Self { std::mem::transmute(bytecode) }
pub fn as_bytes(&self) -> &[u8] { self.0.as_ref() }
pub fn bytes(&self) -> impl Iterator<Item = u8> + '_ { self.0.as_ref().iter().copied() }
}
impl AsRef <[u8]> for Bytecode { fn as_ref(&self) -> &[u8] { self.0.as_ref() } }
impl Borrow<[u8]> for Bytecode { fn borrow(&self) -> &[u8] { self.0.as_ref() } }
impl Debug for Bytecode { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { Debug::fmt(self.0.as_ref(), fmt) } }
impl Deref for Bytecode { fn deref(&self) -> &[u8] { self.0.as_ref() } type Target = [u8]; }