#![cfg_attr(not(feature = "use_std"), no_std)]
use core::net::{Ipv4Addr, Ipv6Addr};
use untrusted::{EndOfInput, Input, Reader};
pub use crate::error::Error;
#[cfg(feature = "use_std")]
use std::ffi::CString;
pub trait ReaderExt<'a> {
fn read_byte(&mut self) -> Result<u8, EndOfInput>;
fn read_bytes(&mut self, num_bytes: usize) -> Result<Input<'a>, EndOfInput>;
fn read_be<T: FromReader>(&mut self) -> Result<T, Error>;
fn read_le<T: FromReader>(&mut self) -> Result<T, Error>;
fn read_partial<F, R, E>(&mut self, read: F) -> Result<(Input<'a>, R), E>
where
F: FnOnce(&mut Reader<'a>) -> Result<R, E>;
#[inline]
fn read_array<const N: usize>(&mut self) -> Result<&'a [u8; N], Error> {
self.read_bytes_less_safe(N)
.and_then(|s| s.as_array().ok_or(Error::EndOfInput))
}
#[inline(always)]
fn read_u8(&mut self) -> Result<u8, Error> {
match self.read_byte() {
Ok(v) => Ok(v),
Err(EndOfInput) => Err(Error::EndOfInput),
}
}
#[inline]
fn read_u16be(&mut self) -> Result<u16, Error> {
self.read_be()
}
#[inline]
fn read_u24be(&mut self) -> Result<u32, Error> {
let b1 = u32::from(self.read_u16be()?);
let b2 = u32::from(self.read_u8()?);
Ok((b1 << 8) + b2)
}
#[inline]
fn read_u32be(&mut self) -> Result<u32, Error> {
self.read_be()
}
#[inline]
fn read_u48be(&mut self) -> Result<u64, Error> {
let b1 = u64::from(self.read_u24be()?);
let b2 = u64::from(self.read_u24be()?);
Ok((b1 << 24) + b2)
}
#[inline]
fn read_u64be(&mut self) -> Result<u64, Error> {
self.read_be()
}
#[inline]
fn read_u128be(&mut self) -> Result<u128, Error> {
self.read_be()
}
#[inline]
fn read_u16le(&mut self) -> Result<u16, Error> {
self.read_le()
}
#[inline]
fn read_u24le(&mut self) -> Result<u32, Error> {
let b2 = u32::from(self.read_u8()?);
let b1 = u32::from(self.read_u16le()?);
Ok((b1 << 8) + b2)
}
#[inline]
fn read_u32le(&mut self) -> Result<u32, Error> {
self.read_le()
}
#[inline]
fn read_u48le(&mut self) -> Result<u64, Error> {
let b2 = u64::from(self.read_u24le()?);
let b1 = u64::from(self.read_u24le()?);
Ok((b1 << 24) + b2)
}
#[inline]
fn read_u64le(&mut self) -> Result<u64, Error> {
self.read_le()
}
#[inline]
fn read_u128le(&mut self) -> Result<u128, Error> {
self.read_le()
}
#[inline]
fn read_i8(&mut self) -> Result<i8, Error> {
Ok(self.read_u8()? as i8)
}
#[inline]
fn read_i16be(&mut self) -> Result<i16, Error> {
self.read_be()
}
#[inline]
fn read_i24be(&mut self) -> Result<i32, Error> {
let b1 = i32::from(self.read_i16be()?);
let b2 = i32::from(self.read_u8()?);
Ok((b1 << 8) + b2)
}
#[inline]
fn read_i32be(&mut self) -> Result<i32, Error> {
self.read_be()
}
#[inline]
fn read_i48be(&mut self) -> Result<i64, Error> {
let b1 = i64::from(self.read_i24be()?);
let b2 = i64::from(self.read_u24be()?);
Ok((b1 << 24) + b2)
}
#[inline]
fn read_i64be(&mut self) -> Result<i64, Error> {
self.read_be()
}
#[inline]
fn read_i128be(&mut self) -> Result<i128, Error> {
self.read_be()
}
#[inline]
fn read_i16le(&mut self) -> Result<i16, Error> {
self.read_le()
}
#[inline]
fn read_i24le(&mut self) -> Result<i32, Error> {
let b2 = i32::from(self.read_u8()?);
let b1 = i32::from(self.read_i16le()?);
Ok((b1 << 8) + b2)
}
#[inline]
fn read_i32le(&mut self) -> Result<i32, Error> {
self.read_le()
}
#[inline]
fn read_i48le(&mut self) -> Result<i64, Error> {
let b2 = i64::from(self.read_u24le()?);
let b1 = i64::from(self.read_i24le()?);
Ok((b1 << 24) + b2)
}
#[inline]
fn read_i64le(&mut self) -> Result<i64, Error> {
self.read_le()
}
#[inline]
fn read_i128le(&mut self) -> Result<i128, Error> {
self.read_le()
}
#[inline]
fn read_bytes_less_safe(&mut self, num_bytes: usize) -> Result<&'a [u8], Error> {
Ok(self.read_bytes(num_bytes).map(|v| v.as_slice_less_safe())?)
}
#[inline]
#[cfg(feature = "use_std")]
fn read_utf8(&mut self, num_bytes: usize) -> Result<&'a str, Error> {
let buf = self.read_bytes_less_safe(num_bytes)?;
Ok(std::str::from_utf8(buf)?)
}
#[inline]
#[cfg(feature = "use_std")]
fn read_utf16(&mut self, num_bytes: usize) -> Result<String, Error> {
if !num_bytes.is_multiple_of(2) {
return Err(Error::ParseError);
}
let len16 = num_bytes / 2;
let mut buf: Vec<u16> = Vec::with_capacity(len16);
for _ in 0..len16 {
let b = self.read_u16be()?;
buf.push(b);
}
Ok(String::from_utf16(&buf)?)
}
#[inline]
fn read_ipv4addr(&mut self) -> Result<Ipv4Addr, Error> {
self.read_u32be().map(Ipv4Addr::from_bits)
}
#[inline]
fn read_ipv6addr(&mut self) -> Result<Ipv6Addr, Error> {
self.read_u128be().map(Ipv6Addr::from_bits)
}
#[inline]
#[cfg(feature = "use_std")]
fn read_cstring(&mut self, max_num_bytes: usize) -> Result<CString, Error> {
let reader = |input: &mut Reader<'_>| -> Result<(), Error> {
for _ in 0..max_num_bytes {
if input.peek(0) {
return Ok(());
}
let _ = input.read_byte()?;
}
Err(Error::ParseError)
};
let (input, ()) = self.read_partial(reader)?;
let _ = self.read_byte()?;
Ok(CString::new(input.as_slice_less_safe())?)
}
}
impl<'a> ReaderExt<'a> for Reader<'a> {
#[inline]
fn read_byte(&mut self) -> Result<u8, EndOfInput> {
self.read_byte()
}
#[inline]
fn read_bytes(&mut self, num_bytes: usize) -> Result<Input<'a>, EndOfInput> {
self.read_bytes(num_bytes)
}
#[inline]
fn read_be<T: FromReader>(&mut self) -> Result<T, Error> {
FromReader::read_be(self)
}
#[inline]
fn read_le<T: FromReader>(&mut self) -> Result<T, Error> {
FromReader::read_le(self)
}
#[inline]
fn read_partial<F, R, E>(&mut self, read: F) -> Result<(Input<'a>, R), E>
where
F: FnOnce(&mut Reader<'a>) -> Result<R, E>,
{
self.read_partial(read)
}
}
pub trait FromReader: Sized {
fn read_be(_: &mut Reader<'_>) -> Result<Self, Error>;
fn read_le(_: &mut Reader<'_>) -> Result<Self, Error>;
}
macro_rules! read_unsigned {
($type:ty) => {
#[inline(always)]
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_array().map(|arr| <$type>::from_be_bytes(*arr))
}
#[inline(always)]
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_array().map(|arr| <$type>::from_le_bytes(*arr))
}
};
}
macro_rules! read_signed {
($type:ty) => {
#[inline(always)]
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
let r = reader.read_be::<$type>()?;
Ok(r as Self)
}
#[inline(always)]
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
let r = reader.read_le::<$type>()?;
Ok(r as Self)
}
};
}
impl FromReader for u8 {
#[inline(always)]
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u8()
}
#[inline(always)]
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u8()
}
}
impl FromReader for u16 {
read_unsigned!(u16);
}
impl FromReader for u32 {
read_unsigned!(u32);
}
impl FromReader for u64 {
read_unsigned!(u64);
}
impl FromReader for u128 {
read_unsigned!(u128);
}
impl FromReader for i8 {
read_signed!(u8);
}
impl FromReader for i16 {
read_signed!(u16);
}
impl FromReader for i32 {
read_signed!(u32);
}
impl FromReader for i64 {
read_signed!(u64);
}
impl FromReader for i128 {
read_signed!(u128);
}
impl FromReader for Ipv4Addr {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u32be().map(Ipv4Addr::from_bits)
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u32le().map(Ipv4Addr::from_bits)
}
}
impl FromReader for Ipv6Addr {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u128be().map(Ipv6Addr::from_bits)
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u128le().map(Ipv6Addr::from_bits)
}
}
impl FromReader for Box<[u8]> {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
let buf = reader.read_bytes_to_end().as_slice_less_safe();
Ok(buf.into())
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
Box::read_be(reader)
}
}
impl FromReader for Vec<u8> {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
let buf = reader.read_bytes_to_end().as_slice_less_safe();
Ok(buf.to_vec())
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
Vec::read_be(reader)
}
}
impl FromReader for Box<str> {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
let buf = reader.read_bytes_to_end().as_slice_less_safe();
if let Ok(s) = std::str::from_utf8(buf) {
return Ok(s.into());
}
Err(Error::ParseError)
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
Box::read_be(reader)
}
}
impl FromReader for String {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
let buf = reader.read_bytes_to_end().as_slice_less_safe();
if let Ok(s) = std::str::from_utf8(buf) {
return Ok(String::from(s));
}
Err(Error::ParseError)
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
String::read_be(reader)
}
}
pub trait Readable {
type Output;
fn read(input: &mut Reader<'_>) -> Result<Self::Output, Error>;
}
mod error {
#[cfg(feature = "use_std")]
use std::ffi::NulError;
#[cfg(feature = "use_std")]
use std::fmt;
#[cfg(feature = "use_std")]
use std::str::Utf8Error;
#[cfg(feature = "use_std")]
use std::string::FromUtf16Error;
use untrusted::EndOfInput;
#[derive(Debug, PartialEq)]
pub enum Error {
EndOfInput,
ParseError,
InvalidValue,
UnknownError,
}
#[cfg(feature = "use_std")]
impl std::error::Error for Error {}
#[cfg(feature = "use_std")]
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Error::EndOfInput => f.write_str("end of input was reached unexpectedly"),
Error::ParseError => f.write_str("failed to parse data into a more specific type"),
Error::InvalidValue => f.write_str("parsed data contained invalid value"),
Error::UnknownError => f.write_str("reading failed with an unknown error"),
}
}
}
impl From<EndOfInput> for Error {
fn from(_: EndOfInput) -> Self {
Error::EndOfInput
}
}
#[cfg(feature = "use_std")]
impl From<Utf8Error> for Error {
fn from(_: Utf8Error) -> Self {
Error::ParseError
}
}
#[cfg(feature = "use_std")]
impl From<FromUtf16Error> for Error {
fn from(_: FromUtf16Error) -> Self {
Error::ParseError
}
}
#[cfg(feature = "use_std")]
impl From<NulError> for Error {
fn from(_: NulError) -> Self {
Error::ParseError
}
}
}