use std::io::Read;
use std::io::Result;
use std::io::Seek;
use std::io::SeekFrom;
use crate::std_io::ReadSeek;
use crate::std_io::ext::internal::read_ext_impl;
pub trait ReadSeekExt: Read + Seek {
fn peek_exact_or_eof(&mut self, buffer: &mut [u8]) -> Result<usize>;
fn read_exact_or_eof_at(&mut self, offset: u64, buffer: &mut [u8]) -> Result<usize>;
}
fn peek_exact_or_eof_impl(reader: &mut dyn ReadSeek, buffer: &mut [u8]) -> Result<usize> {
let position = reader.stream_position()?;
let read_result = read_ext_impl::read_exact_or_eof(reader, buffer);
let restore_result = reader.seek(SeekFrom::Start(position));
match (read_result, restore_result) {
(Ok(count), Ok(_)) => Ok(count),
(Err(error), Ok(_)) => Err(error),
(_, Err(error)) => Err(error),
}
}
fn read_exact_or_eof_at_impl(reader: &mut dyn ReadSeek, offset: u64, buffer: &mut [u8]) -> Result<usize> {
let position = reader.stream_position()?;
let read_result = match reader.seek(SeekFrom::Start(offset)) {
Ok(_) => read_ext_impl::read_exact_or_eof(reader, buffer),
Err(error) => Err(error),
};
let restore_result = reader.seek(SeekFrom::Start(position));
match (read_result, restore_result) {
(Ok(count), Ok(_)) => Ok(count),
(Err(error), Ok(_)) => Err(error),
(_, Err(error)) => Err(error),
}
}
impl<T> ReadSeekExt for T
where
T: Read + Seek + ?Sized,
{
#[inline(always)]
fn peek_exact_or_eof(&mut self, buffer: &mut [u8]) -> Result<usize> {
let mut reader = self;
peek_exact_or_eof_impl(&mut reader, buffer)
}
#[inline(always)]
fn read_exact_or_eof_at(&mut self, offset: u64, buffer: &mut [u8]) -> Result<usize> {
let mut reader = self;
read_exact_or_eof_at_impl(&mut reader, offset, buffer)
}
}