#[cfg(test)]
mod tests;
use crate::types::TypeIndex;
use bstr::{BStr, ByteSlice};
use std::mem::{size_of, take};
use zerocopy::byteorder::{I16, I32, I64, LE, U16, U32, U64};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned, I128, U128};
pub use crate::types::number::Number;
#[derive(Clone)]
pub struct Parser<'a> {
pub bytes: &'a [u8],
}
impl<'a> Parser<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
Self { bytes }
}
pub fn peek_rest(&self) -> &'a [u8] {
self.bytes
}
pub fn take_rest(&mut self) -> &'a [u8] {
take(&mut self.bytes)
}
pub fn into_rest(self) -> &'a [u8] {
self.bytes
}
pub fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
pub fn len(&self) -> usize {
self.bytes.len()
}
#[inline(always)]
pub fn needs(&self, n: usize) -> Result<(), ParserError> {
if n <= self.bytes.len() {
Ok(())
} else {
Err(ParserError::new())
}
}
#[inline(always)]
pub fn bytes(&mut self, n: usize) -> Result<&'a [u8], ParserError> {
if self.bytes.len() < n {
return Err(ParserError::new());
}
let (lo, hi) = self.bytes.split_at(n);
self.bytes = hi;
Ok(lo)
}
pub fn skip(&mut self, n: usize) -> Result<(), ParserError> {
if self.bytes.len() < n {
return Err(ParserError::new());
}
self.bytes = &self.bytes[n..];
Ok(())
}
#[inline(always)]
pub fn get<T: FromBytes + Unaligned + KnownLayout + Immutable>(
&mut self,
) -> Result<&'a T, ParserError> {
if let Ok((value, rest)) = T::ref_from_prefix(self.bytes) {
self.bytes = rest;
Ok(value)
} else {
Err(ParserError::new())
}
}
#[inline(always)]
pub fn copy<T: FromBytes + Unaligned>(&mut self) -> Result<T, ParserError> {
let item = self.bytes(size_of::<T>())?;
Ok(T::read_from_bytes(item).unwrap())
}
#[inline(always)]
pub fn parse<T: Parse<'a>>(&mut self) -> Result<T, ParserError> {
T::from_parser(self)
}
pub fn slice<T: FromBytes + Unaligned + Immutable>(
&mut self,
len: usize,
) -> Result<&'a [T], ParserError> {
if let Ok((lo, hi)) = <[T]>::ref_from_prefix_with_elems(self.bytes, len) {
self.bytes = hi;
Ok(lo)
} else {
Err(ParserError::new())
}
}
pub fn array<const N: usize>(&mut self) -> Result<[u8; N], ParserError> {
let s = self.bytes(N)?;
Ok(<[u8; N]>::try_from(s).unwrap())
}
pub fn u8(&mut self) -> Result<u8, ParserError> {
let b = self.bytes(1)?;
Ok(b[0])
}
pub fn i8(&mut self) -> Result<i8, ParserError> {
let b = self.bytes(1)?;
Ok(b[0] as i8)
}
pub fn i16(&mut self) -> Result<i16, ParserError> {
Ok(self.copy::<I16<LE>>()?.get())
}
pub fn i32(&mut self) -> Result<i32, ParserError> {
Ok(self.copy::<I32<LE>>()?.get())
}
pub fn i64(&mut self) -> Result<i64, ParserError> {
Ok(self.copy::<I64<LE>>()?.get())
}
pub fn u16(&mut self) -> Result<u16, ParserError> {
Ok(self.copy::<U16<LE>>()?.get())
}
pub fn u32(&mut self) -> Result<u32, ParserError> {
Ok(self.copy::<U32<LE>>()?.get())
}
pub fn u64(&mut self) -> Result<u64, ParserError> {
Ok(self.copy::<U64<LE>>()?.get())
}
pub fn u128(&mut self) -> Result<u128, ParserError> {
Ok(self.copy::<U128<LE>>()?.get())
}
pub fn i128(&mut self) -> Result<i128, ParserError> {
Ok(self.copy::<I128<LE>>()?.get())
}
pub fn f32(&mut self) -> Result<f32, ParserError> {
let bytes: [u8; 4] = self.copy()?;
Ok(f32::from_le_bytes(bytes))
}
pub fn f64(&mut self) -> Result<f64, ParserError> {
let bytes: [u8; 8] = self.copy()?;
Ok(f64::from_le_bytes(bytes))
}
pub fn skip_strz(&mut self) -> Result<(), ParserError> {
for i in 0..self.bytes.len() {
if self.bytes[i] == 0 {
self.bytes = &self.bytes[i + 1..];
return Ok(());
}
}
Err(ParserError::new())
}
pub fn strz(&mut self) -> Result<&'a BStr, ParserError> {
for i in 0..self.bytes.len() {
if self.bytes[i] == 0 {
let str_bytes = &self.bytes[..i];
self.bytes = &self.bytes[i + 1..];
return Ok(BStr::new(str_bytes));
}
}
Err(ParserError::new())
}
pub fn strt_raw(&mut self) -> Result<&'a BStr, ParserError> {
let len = self.u8()?;
let bytes = self.bytes(len as usize)?;
Ok(BStr::new(bytes))
}
pub fn strt(&mut self) -> Result<&'a str, ParserError> {
let bytes = self.strt_raw()?;
if let Ok(s) = core::str::from_utf8(bytes.as_ref()) {
Ok(s)
} else {
Err(ParserError::new())
}
}
pub fn type_index(&mut self) -> Result<TypeIndex, ParserError> {
Ok(TypeIndex(self.u32()?))
}
pub fn number(&mut self) -> Result<crate::types::number::Number<'a>, ParserError> {
self.parse()
}
}
pub struct ParserMut<'a> {
pub bytes: &'a mut [u8],
}
#[allow(missing_docs)]
impl<'a> ParserMut<'a> {
pub fn new(bytes: &'a mut [u8]) -> Self {
Self { bytes }
}
pub fn peek_rest(&self) -> &[u8] {
self.bytes
}
pub fn peek_rest_mut(&mut self) -> &mut [u8] {
self.bytes
}
pub fn into_rest(self) -> &'a mut [u8] {
self.bytes
}
pub fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
pub fn len(&self) -> usize {
self.bytes.len()
}
pub fn skip(&mut self, n: usize) -> Result<(), ParserError> {
if n <= self.bytes.len() {
let b = take(&mut self.bytes);
self.bytes = &mut b[n..];
Ok(())
} else {
Err(ParserError::new())
}
}
#[inline(always)]
pub fn bytes(&mut self, n: usize) -> Result<&'a [u8], ParserError> {
if self.bytes.len() < n {
return Err(ParserError::new());
}
let (lo, hi) = take(&mut self.bytes).split_at_mut(n);
self.bytes = hi;
Ok(lo)
}
#[inline(always)]
pub fn bytes_mut(&mut self, n: usize) -> Result<&'a mut [u8], ParserError> {
if self.bytes.len() < n {
return Err(ParserError::new());
}
let (lo, hi) = take(&mut self.bytes).split_at_mut(n);
self.bytes = hi;
Ok(lo)
}
#[inline(always)]
pub fn get<T: FromBytes + Unaligned + Immutable + KnownLayout>(
&mut self,
) -> Result<&'a T, ParserError> {
let bytes = self.bytes(size_of::<T>())?;
Ok(T::ref_from_bytes(bytes).unwrap())
}
#[inline(always)]
pub fn get_mut<T: FromBytes + IntoBytes + Unaligned + Immutable + KnownLayout>(
&mut self,
) -> Result<&'a mut T, ParserError> {
let bytes = self.bytes_mut(size_of::<T>())?;
Ok(T::mut_from_bytes(bytes).unwrap())
}
#[inline(always)]
pub fn copy<T: FromBytes + Unaligned + Immutable>(&mut self) -> Result<T, ParserError> {
let item = self.bytes(size_of::<T>())?;
Ok(T::read_from_bytes(item).unwrap())
}
pub fn slice_mut<T: FromBytes + IntoBytes + Unaligned>(
&mut self,
len: usize,
) -> Result<&'a mut [T], ParserError> {
let d = take(&mut self.bytes);
if let Ok((lo, hi)) = <[T]>::mut_from_prefix_with_elems(d, len) {
self.bytes = hi;
Ok(lo)
} else {
Err(ParserError::new())
}
}
pub fn array<const N: usize>(&mut self) -> Result<[u8; N], ParserError> {
let s = self.bytes(N)?;
Ok(<[u8; N]>::try_from(s).unwrap())
}
pub fn u8(&mut self) -> Result<u8, ParserError> {
let b = self.bytes(1)?;
Ok(b[0])
}
pub fn i8(&mut self) -> Result<i8, ParserError> {
let b = self.bytes(1)?;
Ok(b[0] as i8)
}
pub fn i16(&mut self) -> Result<i16, ParserError> {
Ok(self.copy::<I16<LE>>()?.get())
}
pub fn i32(&mut self) -> Result<i32, ParserError> {
Ok(self.copy::<I32<LE>>()?.get())
}
pub fn i64(&mut self) -> Result<i64, ParserError> {
Ok(self.copy::<I64<LE>>()?.get())
}
pub fn u16(&mut self) -> Result<u16, ParserError> {
Ok(self.copy::<U16<LE>>()?.get())
}
pub fn u32(&mut self) -> Result<u32, ParserError> {
Ok(self.copy::<U32<LE>>()?.get())
}
pub fn u64(&mut self) -> Result<u64, ParserError> {
Ok(self.copy::<U64<LE>>()?.get())
}
pub fn skip_strz(&mut self) -> Result<(), ParserError> {
for i in 0..self.bytes.len() {
if self.bytes[i] == 0 {
let stolen_bytes = take(&mut self.bytes);
self.bytes = &mut stolen_bytes[i + 1..];
return Ok(());
}
}
Err(ParserError::new())
}
pub fn strz(&mut self) -> Result<&'a mut BStr, ParserError> {
for i in 0..self.bytes.len() {
if self.bytes[i] == 0 {
let stolen_bytes = take(&mut self.bytes);
let (str_bytes, hi) = stolen_bytes.split_at_mut(i);
self.bytes = &mut hi[1..];
return Ok(str_bytes.as_bstr_mut());
}
}
Err(ParserError::new())
}
pub fn type_index(&mut self) -> Result<TypeIndex, ParserError> {
Ok(TypeIndex(self.u32()?))
}
pub fn skip_number(&mut self) -> Result<(), ParserError> {
let mut p = Parser::new(self.bytes);
let len_before = p.len();
let _ = p.number()?;
let num_len = len_before - p.len();
self.skip(num_len)?;
Ok(())
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ParserError;
impl ParserError {
#[cfg_attr(debug_assertions, inline(never))]
#[cfg_attr(not(debug_assertions), inline(always))]
pub fn new() -> Self {
#[cfg(debug_assertions)]
{
tracing::debug!("ParserError");
}
Self
}
}
impl Default for ParserError {
fn default() -> Self {
Self::new()
}
}
impl std::error::Error for ParserError {}
impl std::fmt::Display for ParserError {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
fmt.write_str("Parsing error")
}
}
pub trait Parse<'a>
where
Self: Sized,
{
fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError>;
fn parse(bytes: &'a [u8]) -> Result<Self, ParserError> {
let mut p = Parser::new(bytes);
Self::from_parser(&mut p)
}
}