use std::io;
use std::mem;
mod bit;
mod buf_reader;
mod media_source_stream;
mod monitor_stream;
mod scoped_stream;
pub use bit::*;
pub use buf_reader::BufReader;
pub use media_source_stream::{MediaSourceStream, MediaSourceStreamOptions};
pub use monitor_stream::{Monitor, MonitorStream};
pub use scoped_stream::ScopedStream;
pub trait MediaSource: io::Read + io::Seek + Send + Sync {
fn is_seekable(&self) -> bool;
fn byte_len(&self) -> Option<u64>;
}
impl MediaSource for std::fs::File {
fn is_seekable(&self) -> bool {
match self.metadata() {
Ok(metadata) => metadata.is_file(),
_ => false,
}
}
fn byte_len(&self) -> Option<u64> {
match self.metadata() {
Ok(metadata) => Some(metadata.len()),
_ => None,
}
}
}
impl<T: std::convert::AsRef<[u8]> + Send + Sync> MediaSource for io::Cursor<T> {
fn is_seekable(&self) -> bool {
true
}
fn byte_len(&self) -> Option<u64> {
let inner = self.get_ref();
Some(inner.as_ref().len() as u64)
}
}
pub struct ReadOnlySource<R: io::Read> {
inner: R,
}
impl<R: io::Read + Send> ReadOnlySource<R> {
pub fn new(inner: R) -> Self {
ReadOnlySource { inner }
}
pub fn get_ref(&self) -> &R {
&self.inner
}
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
pub fn into_inner(self) -> R {
self.inner
}
}
impl<R: io::Read + Send + Sync> MediaSource for ReadOnlySource<R> {
fn is_seekable(&self) -> bool {
false
}
fn byte_len(&self) -> Option<u64> {
None
}
}
impl<R: io::Read> io::Read for ReadOnlySource<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: io::Read> io::Seek for ReadOnlySource<R> {
fn seek(&mut self, _: io::SeekFrom) -> io::Result<u64> {
Err(io::Error::other("source does not support seeking"))
}
}
pub trait ReadBytes {
fn read_byte(&mut self) -> io::Result<u8>;
fn read_double_bytes(&mut self) -> io::Result<[u8; 2]>;
fn read_triple_bytes(&mut self) -> io::Result<[u8; 3]>;
fn read_quad_bytes(&mut self) -> io::Result<[u8; 4]>;
fn read_buf(&mut self, buf: &mut [u8]) -> io::Result<usize>;
fn read_buf_exact(&mut self, buf: &mut [u8]) -> io::Result<()>;
#[inline(always)]
fn read_u8(&mut self) -> io::Result<u8> {
self.read_byte()
}
#[inline(always)]
fn read_i8(&mut self) -> io::Result<i8> {
Ok(self.read_byte()? as i8)
}
#[inline(always)]
fn read_u16(&mut self) -> io::Result<u16> {
Ok(u16::from_le_bytes(self.read_double_bytes()?))
}
#[inline(always)]
fn read_i16(&mut self) -> io::Result<i16> {
Ok(i16::from_le_bytes(self.read_double_bytes()?))
}
#[inline(always)]
fn read_be_u16(&mut self) -> io::Result<u16> {
Ok(u16::from_be_bytes(self.read_double_bytes()?))
}
#[inline(always)]
fn read_be_i16(&mut self) -> io::Result<i16> {
Ok(i16::from_be_bytes(self.read_double_bytes()?))
}
#[inline(always)]
fn read_u24(&mut self) -> io::Result<u32> {
let mut buf = [0u8; mem::size_of::<u32>()];
buf[0..3].clone_from_slice(&self.read_triple_bytes()?);
Ok(u32::from_le_bytes(buf))
}
#[inline(always)]
fn read_i24(&mut self) -> io::Result<i32> {
Ok(((self.read_u24()? << 8) as i32) >> 8)
}
#[inline(always)]
fn read_be_u24(&mut self) -> io::Result<u32> {
let mut buf = [0u8; mem::size_of::<u32>()];
buf[0..3].clone_from_slice(&self.read_triple_bytes()?);
Ok(u32::from_be_bytes(buf) >> 8)
}
#[inline(always)]
fn read_be_i24(&mut self) -> io::Result<i32> {
Ok(((self.read_be_u24()? << 8) as i32) >> 8)
}
#[inline(always)]
fn read_u32(&mut self) -> io::Result<u32> {
Ok(u32::from_le_bytes(self.read_quad_bytes()?))
}
#[inline(always)]
fn read_i32(&mut self) -> io::Result<i32> {
Ok(i32::from_le_bytes(self.read_quad_bytes()?))
}
#[inline(always)]
fn read_be_u32(&mut self) -> io::Result<u32> {
Ok(u32::from_be_bytes(self.read_quad_bytes()?))
}
#[inline(always)]
fn read_be_i32(&mut self) -> io::Result<i32> {
Ok(i32::from_be_bytes(self.read_quad_bytes()?))
}
#[inline(always)]
fn read_u64(&mut self) -> io::Result<u64> {
let mut buf = [0u8; mem::size_of::<u64>()];
self.read_buf_exact(&mut buf)?;
Ok(u64::from_le_bytes(buf))
}
#[inline(always)]
fn read_i64(&mut self) -> io::Result<i64> {
let mut buf = [0u8; mem::size_of::<i64>()];
self.read_buf_exact(&mut buf)?;
Ok(i64::from_le_bytes(buf))
}
#[inline(always)]
fn read_be_u64(&mut self) -> io::Result<u64> {
let mut buf = [0u8; mem::size_of::<u64>()];
self.read_buf_exact(&mut buf)?;
Ok(u64::from_be_bytes(buf))
}
#[inline(always)]
fn read_be_i64(&mut self) -> io::Result<i64> {
let mut buf = [0u8; mem::size_of::<i64>()];
self.read_buf_exact(&mut buf)?;
Ok(i64::from_be_bytes(buf))
}
#[inline(always)]
fn read_f32(&mut self) -> io::Result<f32> {
Ok(f32::from_le_bytes(self.read_quad_bytes()?))
}
#[inline(always)]
fn read_be_f32(&mut self) -> io::Result<f32> {
Ok(f32::from_be_bytes(self.read_quad_bytes()?))
}
#[inline(always)]
fn read_f64(&mut self) -> io::Result<f64> {
let mut buf = [0u8; mem::size_of::<u64>()];
self.read_buf_exact(&mut buf)?;
Ok(f64::from_le_bytes(buf))
}
#[inline(always)]
fn read_be_f64(&mut self) -> io::Result<f64> {
let mut buf = [0u8; mem::size_of::<u64>()];
self.read_buf_exact(&mut buf)?;
Ok(f64::from_be_bytes(buf))
}
fn read_boxed_slice(&mut self, len: usize) -> io::Result<Box<[u8]>> {
safe_read_into_boxed_slice(len, |buf| self.read_buf(buf))
}
fn read_boxed_slice_exact(&mut self, len: usize) -> io::Result<Box<[u8]>> {
safe_read_into_boxed_slice(len, |buf| {
self.read_buf_exact(buf)?;
Ok(buf.len())
})
}
#[inline(always)]
fn scan_bytes<'a>(&mut self, pattern: &[u8], buf: &'a mut [u8]) -> io::Result<&'a mut [u8]> {
self.scan_bytes_aligned(pattern, 1, buf)
}
fn scan_bytes_aligned<'a>(
&mut self,
pattern: &[u8],
align: usize,
buf: &'a mut [u8],
) -> io::Result<&'a mut [u8]>;
fn ignore_bytes(&mut self, count: u64) -> io::Result<()>;
fn pos(&self) -> u64;
}
impl<R: ReadBytes> ReadBytes for &mut R {
#[inline(always)]
fn read_byte(&mut self) -> io::Result<u8> {
(*self).read_byte()
}
#[inline(always)]
fn read_double_bytes(&mut self) -> io::Result<[u8; 2]> {
(*self).read_double_bytes()
}
#[inline(always)]
fn read_triple_bytes(&mut self) -> io::Result<[u8; 3]> {
(*self).read_triple_bytes()
}
#[inline(always)]
fn read_quad_bytes(&mut self) -> io::Result<[u8; 4]> {
(*self).read_quad_bytes()
}
#[inline(always)]
fn read_buf(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(*self).read_buf(buf)
}
#[inline(always)]
fn read_buf_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
(*self).read_buf_exact(buf)
}
#[inline(always)]
fn scan_bytes_aligned<'a>(
&mut self,
pattern: &[u8],
align: usize,
buf: &'a mut [u8],
) -> io::Result<&'a mut [u8]> {
(*self).scan_bytes_aligned(pattern, align, buf)
}
#[inline(always)]
fn ignore_bytes(&mut self, count: u64) -> io::Result<()> {
(*self).ignore_bytes(count)
}
#[inline(always)]
fn pos(&self) -> u64 {
(**self).pos()
}
}
impl<S: SeekBuffered> SeekBuffered for &mut S {
fn ensure_seekback_buffer(&mut self, len: usize) {
(*self).ensure_seekback_buffer(len)
}
fn unread_buffer_len(&self) -> usize {
(**self).unread_buffer_len()
}
fn read_buffer_len(&self) -> usize {
(**self).read_buffer_len()
}
fn seek_buffered(&mut self, pos: u64) -> u64 {
(*self).seek_buffered(pos)
}
fn seek_buffered_rel(&mut self, delta: isize) -> u64 {
(*self).seek_buffered_rel(delta)
}
}
pub trait SeekBuffered {
fn ensure_seekback_buffer(&mut self, len: usize);
fn unread_buffer_len(&self) -> usize;
fn read_buffer_len(&self) -> usize;
fn seek_buffered(&mut self, pos: u64) -> u64;
fn seek_buffered_rel(&mut self, delta: isize) -> u64;
fn seek_buffered_rev(&mut self, delta: usize) {
assert!(delta < isize::MAX as usize);
self.seek_buffered_rel(-(delta as isize));
}
}
impl<F: FiniteStream> FiniteStream for &mut F {
fn byte_len(&self) -> u64 {
(**self).byte_len()
}
fn bytes_read(&self) -> u64 {
(**self).bytes_read()
}
fn bytes_available(&self) -> u64 {
(**self).bytes_available()
}
}
pub trait FiniteStream {
fn byte_len(&self) -> u64;
fn bytes_read(&self) -> u64;
fn bytes_available(&self) -> u64;
}
fn safe_read_into_boxed_slice<R>(len: usize, mut read: R) -> io::Result<Box<[u8]>>
where
R: FnMut(&mut [u8]) -> io::Result<usize>,
{
const INIT_MAX_READ_LEN: usize = 4 * 1024 * 1024;
const ABS_MAX_READ_LEN: usize = 1 * 1024 * 1024 * 1024;
let mut next_max_read_len = INIT_MAX_READ_LEN;
let mut buf = Vec::new();
while buf.len() < len {
let have_len = buf.len();
let will_read_len = next_max_read_len.min(len - have_len);
next_max_read_len = (2 * next_max_read_len).min(ABS_MAX_READ_LEN);
buf.try_reserve_exact(will_read_len)
.map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
buf.resize(have_len + will_read_len, 0);
let did_read_len = read(&mut buf[have_len..])?;
if did_read_len < will_read_len {
buf.truncate(have_len + did_read_len);
break;
}
}
Ok(buf.into_boxed_slice())
}