1use futures_io::{AsyncRead, AsyncSeek};
2use futures_util::io::{AsyncReadExt, AsyncSeekExt};
3use std::io::SeekFrom;
4use std::marker::PhantomData;
5
6use crate::parser::ParseErrorKind;
7use crate::ParseError;
8
9mod sealed {
10 pub trait Sealed {}
11}
12
13pub struct Seekable;
14pub struct NonSeekable;
15
16impl sealed::Sealed for Seekable {}
17impl sealed::Sealed for NonSeekable {}
18
19pub trait ReadCapability: sealed::Sealed {}
20
21impl ReadCapability for NonSeekable {}
22
23impl ReadCapability for Seekable {}
24
25pub struct Mp4Reader<R, C: ReadCapability> {
26 reader: R,
27 pub(crate) current_offset: usize,
28 peek_buffer: Vec<u8>,
29 _capability: PhantomData<C>,
30}
31
32impl<R: AsyncRead + Unpin + Send> Mp4Reader<R, NonSeekable> {
33 pub fn new(reader: R) -> Self {
34 Self {
35 reader,
36 current_offset: 0,
37 peek_buffer: Vec::new(),
38 _capability: PhantomData,
39 }
40 }
41}
42
43impl<R: AsyncRead + Unpin + Send, C: ReadCapability> Mp4Reader<R, C> {
44 pub(crate) async fn peek_exact(&mut self, buf: &mut [u8]) -> Result<(), ParseError> {
45 let size = buf.len();
46 if self.peek_buffer.len() < size {
47 let mut temp_buf = vec![0u8; size - self.peek_buffer.len()];
48 self.reader.read_exact(&mut temp_buf).await.map_err(|e| {
49 if e.kind() == std::io::ErrorKind::UnexpectedEof {
50 return ParseError {
51 kind: ParseErrorKind::Eof,
52 location: Some((self.current_offset, size)),
53 source: Some(Box::new(e)),
54 };
55 }
56 ParseError {
57 kind: ParseErrorKind::Io,
58 location: Some((self.current_offset, size)),
59 source: Some(Box::new(e)),
60 }
61 })?;
62 self.peek_buffer.extend_from_slice(&temp_buf[..]);
63 }
64 buf.copy_from_slice(&self.peek_buffer[..size]);
65 Ok(())
66 }
67
68 pub(crate) async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ParseError> {
69 self.peek_exact(buf).await?;
70 self.peek_buffer.drain(..buf.len());
71 self.current_offset += buf.len();
72 Ok(())
73 }
74
75 pub(crate) async fn read_data(&mut self, size: usize) -> Result<Vec<u8>, ParseError> {
76 let mut data = vec![0u8; size];
77 self.read_exact(&mut data).await?;
78 Ok(data)
79 }
80}
81
82impl<R: AsyncRead + AsyncSeek + Unpin + Send> Mp4Reader<R, Seekable> {
83 pub fn new(reader: R) -> Self {
84 Self {
85 reader,
86 current_offset: 0,
87 peek_buffer: Vec::new(),
88 _capability: PhantomData,
89 }
90 }
91
92 pub(crate) async fn seek(&mut self, pos: SeekFrom) -> Result<(), ParseError> {
93 match self.reader.seek(pos).await {
94 Ok(offset) => {
95 self.current_offset = offset as usize;
96 self.peek_buffer = Vec::new();
97 Ok(())
98 }
99 Err(err) => Err(ParseError {
100 kind: ParseErrorKind::Io,
101 location: None,
102 source: Some(Box::new(err)),
103 }),
104 }
105 }
106}