#[cfg(feature = "alloc")]
use alloc::{vec, vec::Vec};
#[cfg(feature = "std")]
use core::cmp;
use core::mem;
#[cfg(feature = "std")]
use std::io::{self, Read as StdRead};
use crate::error::{Error, ErrorCode, Result};
#[cfg(not(feature = "unsealed_read_write"))]
pub trait Read<'de>: private::Sealed {
#[doc(hidden)]
fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
self.clear_buffer();
self.read_to_buffer(n)?;
Ok(self.take_buffer())
}
#[doc(hidden)]
fn next(&mut self) -> Result<Option<u8>>;
#[doc(hidden)]
fn peek(&mut self) -> Result<Option<u8>>;
#[doc(hidden)]
fn clear_buffer(&mut self);
#[doc(hidden)]
fn read_to_buffer(&mut self, n: usize) -> Result<()>;
#[doc(hidden)]
fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
#[doc(hidden)]
fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
#[doc(hidden)]
fn discard(&mut self);
#[doc(hidden)]
fn offset(&self) -> u64;
}
#[cfg(feature = "unsealed_read_write")]
pub trait Read<'de> {
fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
self.clear_buffer();
self.read_to_buffer(n)?;
Ok(self.take_buffer())
}
fn next(&mut self) -> Result<Option<u8>>;
fn peek(&mut self) -> Result<Option<u8>>;
fn clear_buffer(&mut self);
fn read_to_buffer(&mut self, n: usize) -> Result<()>;
fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
fn discard(&mut self);
fn offset(&self) -> u64;
}
pub trait Offset {
fn byte_offset(&self) -> usize;
}
pub enum EitherLifetime<'short, 'long> {
Short(&'short [u8]),
Long(&'long [u8]),
}
#[cfg(not(feature = "unsealed_read_write"))]
mod private {
pub trait Sealed {}
}
#[cfg(feature = "std")]
#[derive(Debug)]
pub struct IoRead<R>
where
R: io::Read,
{
reader: OffsetReader<R>,
scratch: Vec<u8>,
ch: Option<u8>,
}
#[cfg(feature = "std")]
impl<R> IoRead<R>
where
R: io::Read,
{
pub fn new(reader: R) -> IoRead<R> {
IoRead {
reader: OffsetReader { reader, offset: 0 },
scratch: vec![],
ch: None,
}
}
#[inline]
fn next_inner(&mut self) -> Result<Option<u8>> {
let mut buf = [0; 1];
loop {
match self.reader.read(&mut buf) {
Ok(0) => return Ok(None),
Ok(_) => return Ok(Some(buf[0])),
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(Error::io(e)),
}
}
}
}
#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
impl<R> private::Sealed for IoRead<R> where R: io::Read {}
#[cfg(feature = "std")]
impl<'de, R> Read<'de> for IoRead<R>
where
R: io::Read,
{
#[inline]
fn next(&mut self) -> Result<Option<u8>> {
match self.ch.take() {
Some(ch) => Ok(Some(ch)),
None => self.next_inner(),
}
}
#[inline]
fn peek(&mut self) -> Result<Option<u8>> {
match self.ch {
Some(ch) => Ok(Some(ch)),
None => {
self.ch = self.next_inner()?;
Ok(self.ch)
}
}
}
fn read_to_buffer(&mut self, mut n: usize) -> Result<()> {
self.scratch.reserve(cmp::min(n, 16 * 1024));
if n == 0 {
return Ok(());
}
if let Some(ch) = self.ch.take() {
self.scratch.push(ch);
n -= 1;
}
let transfer_result = {
let reference = self.reader.by_ref();
let mut taken = reference.take(n as u64);
taken.read_to_end(&mut self.scratch)
};
match transfer_result {
Ok(r) if r == n => Ok(()),
Ok(_) => Err(Error::syntax(
ErrorCode::EofWhileParsingValue,
self.offset(),
)),
Err(e) => Err(Error::io(e)),
}
}
fn clear_buffer(&mut self) {
self.scratch.clear();
}
fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de> {
EitherLifetime::Short(&self.scratch)
}
fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
self.reader.read_exact(buf).map_err(|e| {
if e.kind() == io::ErrorKind::UnexpectedEof {
Error::syntax(ErrorCode::EofWhileParsingValue, self.offset())
} else {
Error::io(e)
}
})
}
#[inline]
fn discard(&mut self) {
self.ch = None;
}
fn offset(&self) -> u64 {
self.reader.offset
}
}
#[cfg(feature = "std")]
impl<R> Offset for IoRead<R>
where
R: std::io::Read,
{
fn byte_offset(&self) -> usize {
self.offset() as usize
}
}
#[cfg(feature = "std")]
#[derive(Debug)]
struct OffsetReader<R> {
reader: R,
offset: u64,
}
#[cfg(feature = "std")]
impl<R> io::Read for OffsetReader<R>
where
R: io::Read,
{
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let r = self.reader.read(buf);
if let Ok(count) = r {
self.offset += count as u64;
}
r
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Debug)]
pub struct SliceRead<'a> {
slice: &'a [u8],
scratch: Vec<u8>,
index: usize,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a> SliceRead<'a> {
pub fn new(slice: &'a [u8]) -> SliceRead<'a> {
SliceRead {
slice,
scratch: vec![],
index: 0,
}
}
fn end(&self, n: usize) -> Result<usize> {
match self.index.checked_add(n) {
Some(end) if end <= self.slice.len() => Ok(end),
_ => Err(Error::syntax(
ErrorCode::EofWhileParsingValue,
self.slice.len() as u64,
)),
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a> Offset for SliceRead<'a> {
#[inline]
fn byte_offset(&self) -> usize {
self.index
}
}
#[cfg(all(
any(feature = "std", feature = "alloc"),
not(feature = "unsealed_read_write")
))]
impl<'a> private::Sealed for SliceRead<'a> {}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a> Read<'a> for SliceRead<'a> {
#[inline]
fn next(&mut self) -> Result<Option<u8>> {
Ok(if self.index < self.slice.len() {
let ch = self.slice[self.index];
self.index += 1;
Some(ch)
} else {
None
})
}
#[inline]
fn peek(&mut self) -> Result<Option<u8>> {
Ok(if self.index < self.slice.len() {
Some(self.slice[self.index])
} else {
None
})
}
fn clear_buffer(&mut self) {
self.scratch.clear();
}
fn read_to_buffer(&mut self, n: usize) -> Result<()> {
let end = self.end(n)?;
let slice = &self.slice[self.index..end];
self.scratch.extend_from_slice(slice);
self.index = end;
Ok(())
}
#[inline]
fn read<'b>(&'b mut self, n: usize) -> Result<EitherLifetime<'b, 'a>> {
let end = self.end(n)?;
let slice = &self.slice[self.index..end];
self.index = end;
Ok(EitherLifetime::Long(slice))
}
fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
EitherLifetime::Short(&self.scratch)
}
#[inline]
fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
let end = self.end(buf.len())?;
buf.copy_from_slice(&self.slice[self.index..end]);
self.index = end;
Ok(())
}
#[inline]
fn discard(&mut self) {
self.index += 1;
}
fn offset(&self) -> u64 {
self.index as u64
}
}
#[derive(Debug)]
pub struct SliceReadFixed<'a, 'b> {
slice: &'a [u8],
scratch: &'b mut [u8],
index: usize,
scratch_index: usize,
}
impl<'a, 'b> SliceReadFixed<'a, 'b> {
pub fn new(slice: &'a [u8], scratch: &'b mut [u8]) -> SliceReadFixed<'a, 'b> {
SliceReadFixed {
slice,
scratch,
index: 0,
scratch_index: 0,
}
}
fn end(&self, n: usize) -> Result<usize> {
match self.index.checked_add(n) {
Some(end) if end <= self.slice.len() => Ok(end),
_ => Err(Error::syntax(
ErrorCode::EofWhileParsingValue,
self.slice.len() as u64,
)),
}
}
fn scratch_end(&self, n: usize) -> Result<usize> {
match self.scratch_index.checked_add(n) {
Some(end) if end <= self.scratch.len() => Ok(end),
_ => Err(Error::scratch_too_small(self.index as u64)),
}
}
}
#[cfg(not(feature = "unsealed_read_write"))]
impl<'a, 'b> private::Sealed for SliceReadFixed<'a, 'b> {}
impl<'a, 'b> Read<'a> for SliceReadFixed<'a, 'b> {
#[inline]
fn next(&mut self) -> Result<Option<u8>> {
Ok(if self.index < self.slice.len() {
let ch = self.slice[self.index];
self.index += 1;
Some(ch)
} else {
None
})
}
#[inline]
fn peek(&mut self) -> Result<Option<u8>> {
Ok(if self.index < self.slice.len() {
Some(self.slice[self.index])
} else {
None
})
}
fn clear_buffer(&mut self) {
self.scratch_index = 0;
}
fn read_to_buffer(&mut self, n: usize) -> Result<()> {
let end = self.end(n)?;
let scratch_end = self.scratch_end(n)?;
let slice = &self.slice[self.index..end];
self.scratch[self.scratch_index..scratch_end].copy_from_slice(&slice);
self.index = end;
self.scratch_index = scratch_end;
Ok(())
}
fn read<'c>(&'c mut self, n: usize) -> Result<EitherLifetime<'c, 'a>> {
let end = self.end(n)?;
let slice = &self.slice[self.index..end];
self.index = end;
Ok(EitherLifetime::Long(slice))
}
fn take_buffer<'c>(&'c mut self) -> EitherLifetime<'c, 'a> {
EitherLifetime::Short(&self.scratch[0..self.scratch_index])
}
#[inline]
fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
let end = self.end(buf.len())?;
buf.copy_from_slice(&self.slice[self.index..end]);
self.index = end;
Ok(())
}
#[inline]
fn discard(&mut self) {
self.index += 1;
}
fn offset(&self) -> u64 {
self.index as u64
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'b> Offset for SliceReadFixed<'a, 'b> {
#[inline]
fn byte_offset(&self) -> usize {
self.index
}
}
#[derive(Debug)]
pub struct MutSliceRead<'a> {
slice: &'a mut [u8],
index: usize,
before: usize,
buffer_end: usize,
}
impl<'a> MutSliceRead<'a> {
pub fn new(slice: &'a mut [u8]) -> MutSliceRead<'a> {
MutSliceRead {
slice,
index: 0,
before: 0,
buffer_end: 0,
}
}
fn end(&self, n: usize) -> Result<usize> {
match self.index.checked_add(n) {
Some(end) if end <= self.slice.len() => Ok(end),
_ => Err(Error::syntax(
ErrorCode::EofWhileParsingValue,
self.slice.len() as u64,
)),
}
}
}
#[cfg(not(feature = "unsealed_read_write"))]
impl<'a> private::Sealed for MutSliceRead<'a> {}
impl<'a> Read<'a> for MutSliceRead<'a> {
#[inline]
fn next(&mut self) -> Result<Option<u8>> {
Ok(if self.index < self.slice.len() {
let ch = self.slice[self.index];
self.index += 1;
Some(ch)
} else {
None
})
}
#[inline]
fn peek(&mut self) -> Result<Option<u8>> {
Ok(if self.index < self.slice.len() {
Some(self.slice[self.index])
} else {
None
})
}
fn clear_buffer(&mut self) {
self.slice = &mut mem::replace(&mut self.slice, &mut [])[self.index..];
self.before += self.index;
self.index = 0;
self.buffer_end = 0;
}
fn read_to_buffer(&mut self, n: usize) -> Result<()> {
let end = self.end(n)?;
debug_assert!(
self.buffer_end <= self.index,
"MutSliceRead invariant violated: scratch buffer exceeds index"
);
self.slice[self.buffer_end..end].rotate_left(self.index - self.buffer_end);
self.buffer_end += n;
self.index = end;
Ok(())
}
fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
let (left, right) = mem::replace(&mut self.slice, &mut []).split_at_mut(self.index);
self.slice = right;
self.before += self.index;
self.index = 0;
let left = &left[..self.buffer_end];
self.buffer_end = 0;
EitherLifetime::Long(left)
}
#[inline]
fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
let end = self.end(buf.len())?;
buf.copy_from_slice(&self.slice[self.index..end]);
self.index = end;
Ok(())
}
#[inline]
fn discard(&mut self) {
self.index += 1;
}
fn offset(&self) -> u64 {
(self.before + self.index) as u64
}
}