#![cfg_attr(not(feature = "use_std"), no_std)]
use untrusted::{EndOfInput, Input, Reader};
pub use crate::error::Error;
#[cfg(feature = "use_std")]
use std::net::{Ipv4Addr, Ipv6Addr};
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>;
#[inline]
fn read_u8(&mut self) -> Result<u8, Error> {
self.read_byte().map_err(From::from)
}
#[inline]
fn read_u16be(&mut self) -> Result<u16, Error> {
self.read_be().map_err(From::from)
}
#[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().map_err(From::from)
}
#[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().map_err(From::from)
}
#[inline]
fn read_u128be(&mut self) -> Result<u128, Error> {
self.read_be().map_err(From::from)
}
#[inline]
fn read_u16le(&mut self) -> Result<u16, Error> {
self.read_le().map_err(From::from)
}
#[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().map_err(From::from)
}
#[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().map_err(From::from)
}
#[inline]
fn read_u128le(&mut self) -> Result<u128, Error> {
self.read_le().map_err(From::from)
}
#[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().map_err(From::from)
}
#[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().map_err(From::from)
}
#[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().map_err(From::from)
}
#[inline]
fn read_i128be(&mut self) -> Result<i128, Error> {
self.read_be().map_err(From::from)
}
#[inline]
fn read_i16le(&mut self) -> Result<i16, Error> {
self.read_le().map_err(From::from)
}
#[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().map_err(From::from)
}
#[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().map_err(From::from)
}
#[inline]
fn read_i128le(&mut self) -> Result<i128, Error> {
self.read_le().map_err(From::from)
}
#[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)?;
std::str::from_utf8(buf).map_err(From::from)
}
#[inline]
#[cfg(feature = "use_std")]
fn read_utf16(&mut self, num_bytes: usize) -> Result<String, Error> {
if (num_bytes % 2) != 0 {
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);
}
String::from_utf16(&buf).map_err(From::from)
}
#[inline]
#[cfg(feature = "use_std")]
fn read_ipv4addr(&mut self) -> Result<Ipv4Addr, Error> {
self.read_u32be().map(Ipv4Addr::from)
}
#[inline]
#[cfg(feature = "use_std")]
fn read_ipv6addr(&mut self) -> Result<Ipv6Addr, Error> {
self.read_u128be().map(Ipv6Addr::from)
}
}
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)
}
}
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]
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
const LEN: usize = core::mem::size_of::<$type>();
let mut arr = [0u8; LEN];
let slice = reader.read_bytes(LEN)?.as_slice_less_safe();
arr.copy_from_slice(slice);
Ok(<$type>::from_be_bytes(arr))
}
#[inline]
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
const LEN: usize = core::mem::size_of::<$type>();
let mut arr = [0u8; LEN];
let slice = reader.read_bytes(LEN)?.as_slice_less_safe();
arr.copy_from_slice(slice);
Ok(<$type>::from_le_bytes(arr))
}
};
}
macro_rules! read_signed {
($type:ty) => {
#[inline]
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
let r = reader.read_be::<$type>()?;
Ok(r as Self)
}
#[inline]
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
let r = reader.read_le::<$type>()?;
Ok(r as Self)
}
};
}
impl FromReader for u8 {
#[inline]
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_byte().map_err(From::from)
}
#[inline]
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_byte().map_err(From::from)
}
}
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);
}
#[cfg(feature = "use_std")]
impl FromReader for Ipv4Addr {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u32be().map(Ipv4Addr::from)
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u32le().map(Ipv4Addr::from)
}
}
#[cfg(feature = "use_std")]
impl FromReader for Ipv6Addr {
fn read_be(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u128be().map(Ipv6Addr::from)
}
fn read_le(reader: &mut Reader<'_>) -> Result<Self, Error> {
reader.read_u128le().map(Ipv6Addr::from)
}
}
mod error {
#[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,
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::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
}
}
}