#![doc=include_str!("../README.md")]
#![cfg_attr(not(feature="std"), no_std)]
#![warn(missing_docs)]
mod decode;
#[cfg(feature="maypanic")]
mod maypanic;
use core::ops::Add;
#[cfg(feature="std")]
use std::{error::Error, fmt::Display};
use bytes::*;
pub use decode::{Decode, DecodeEndian};
#[cfg(feature="maypanic")]
pub use maypanic::ReaderMayPanic;
pub struct Reader {
index: usize,
inner: Bytes,
}
impl Reader {
pub fn new<T: Into<Bytes>>(bytes: T) -> Self {
Self {
index: 0,
inner: bytes.into(),
}
}
#[inline]
fn increment(&mut self, amt: usize) {
self.index = self.index.add(amt).min(self.inner.len())
}
#[inline]
pub fn remaining(&self) -> usize {
self.inner.len().saturating_sub(self.index)
}
#[inline]
pub fn at_least(&self, len: usize) -> bool {
self.remaining() >= len
}
#[inline]
pub fn consumed(&self) -> usize {
self.index
}
pub fn skip(&mut self, amt: usize) {
self.increment(amt)
}
pub fn peek(&self, val: u8) -> bool {
if !self.at_least(1) { return false; }
self.inner[self.index + 1] == val
}
pub fn read_to_end(self) -> Bytes {
if self.index == self.inner.len() {
return Bytes::new()
}
self.inner.slice(self.index..)
}
pub fn subreader(&mut self, len: usize) -> Result<Self, EndOfInput> {
if len == 0 { return Err(EndOfInput); }
Ok(Self::new(self.read_bytes(len)?))
}
pub fn read_byte(&mut self) -> Result<u8, EndOfInput> {
if !self.at_least(1) { return Err(EndOfInput); }
let r = self.inner[self.index];
self.increment(1);
return Ok(r);
}
pub fn read_bytes(&mut self, len: usize) -> Result<Bytes, EndOfInput> {
if !self.at_least(len) { return Err(EndOfInput); }
let old_idx = self.index;
self.increment(len);
Ok(self.inner.slice(old_idx..old_idx+len))
}
pub fn read_slice(&mut self, len: usize) -> Result<&[u8], EndOfInput> {
if !self.at_least(len) { return Err(EndOfInput); }
let old_idx = self.index;
self.increment(len);
Ok(&self.inner[old_idx..old_idx+len])
}
pub fn read_array<const N: usize>(&mut self) -> Result<[u8; N], EndOfInput> {
let slice = self.read_slice(N)?;
let mut array = [0u8; N];
array.copy_from_slice(slice);
Ok(array)
}
pub fn read<T: Decode>(&mut self) -> Result<T, EndOfInput> {
T::decode(self)
}
}
impl AsMut<Reader> for Reader {
#[inline(always)]
fn as_mut(&mut self) -> &mut Reader {
self
}
}
#[cfg(feature="std")]
impl std::io::Read for Reader {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let amt = self.remaining().min(buf.len());
if amt == 0 { return Ok(0) }
buf[..amt].copy_from_slice(self.read_slice(amt).unwrap());
Ok(0)
}
}
impl From<Bytes> for Reader {
#[inline]
fn from(value: Bytes) -> Self {
Self {
index: 0,
inner: value,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct EndOfInput;
#[cfg(feature="std")]
impl Display for EndOfInput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("end of input")
}
}
#[cfg(feature="std")]
impl Error for EndOfInput {}
#[test]
fn static_slice_test() {
let slice: &'static [u8; 20] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
let bytes = Bytes::from_static(slice);
let mut reader = Reader::new(bytes.clone());
assert_eq!(slice, &*reader.read_bytes(20).unwrap());
let mut reader = Reader::new(bytes.clone());
assert_eq!(slice, reader.read_slice(20).unwrap());
let mut reader = Reader::new(bytes.clone());
assert_eq!(slice, &reader.read_array::<20>().unwrap());
let mut reader = Reader::new(bytes.clone());
assert_eq!(&[1,2,3,4,5], &*reader.read_bytes(5).unwrap());
assert_eq!(&[6,7,8,9,10], reader.read_slice(5).unwrap());
assert_eq!(&[11,12,13,14,15], &reader.read_array::<5>().unwrap());
assert_eq!(16, reader.read_byte().unwrap());
assert_eq!(reader.consumed(), 16);
assert_eq!(reader.remaining(), 4);
assert!(reader.at_least(4));
}