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, C: ReadCapability> Mp4Reader<R, C> {
33 pub fn into_inner(self) -> (Vec<u8>, R) {
34 (self.peek_buffer, self.reader)
35 }
36}
37
38impl<R: AsyncRead + Unpin + Send> Mp4Reader<R, NonSeekable> {
39 pub fn new(reader: R) -> Self {
40 Self {
41 reader,
42 current_offset: 0,
43 peek_buffer: Vec::new(),
44 _capability: PhantomData,
45 }
46 }
47}
48
49impl<R: AsyncRead + Unpin + Send, C: ReadCapability> Mp4Reader<R, C> {
50 pub(crate) async fn peek_exact(&mut self, buf: &mut [u8]) -> Result<(), ParseError> {
51 let size = buf.len();
52 if self.peek_buffer.len() < size {
53 let mut temp_buf = vec![0u8; size - self.peek_buffer.len()];
54 self.reader.read_exact(&mut temp_buf).await.map_err(|e| {
55 if e.kind() == std::io::ErrorKind::UnexpectedEof {
56 return ParseError {
57 kind: ParseErrorKind::Eof,
58 location: Some((self.current_offset, size)),
59 source: Some(Box::new(e)),
60 };
61 }
62 ParseError {
63 kind: ParseErrorKind::Io,
64 location: Some((self.current_offset, size)),
65 source: Some(Box::new(e)),
66 }
67 })?;
68 self.peek_buffer.extend_from_slice(&temp_buf[..]);
69 }
70 buf.copy_from_slice(&self.peek_buffer[..size]);
71 Ok(())
72 }
73
74 pub(crate) async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ParseError> {
75 self.peek_exact(buf).await?;
76 self.peek_buffer.drain(..buf.len());
77 self.current_offset += buf.len();
78 Ok(())
79 }
80
81 pub(crate) async fn read_data(&mut self, size: usize) -> Result<Vec<u8>, ParseError> {
82 let mut data = vec![0u8; size];
83 self.read_exact(&mut data).await?;
84 Ok(data)
85 }
86}
87
88impl<R: AsyncRead + AsyncSeek + Unpin + Send> Mp4Reader<R, Seekable> {
89 pub fn new(reader: R) -> Self {
90 Self {
91 reader,
92 current_offset: 0,
93 peek_buffer: Vec::new(),
94 _capability: PhantomData,
95 }
96 }
97
98 pub(crate) async fn seek(&mut self, pos: SeekFrom) -> Result<(), ParseError> {
99 match self.reader.seek(pos).await {
100 Ok(offset) => {
101 self.current_offset = offset as usize;
102 self.peek_buffer = Vec::new();
103 Ok(())
104 }
105 Err(err) => Err(ParseError {
106 kind: ParseErrorKind::Io,
107 location: None,
108 source: Some(Box::new(err)),
109 }),
110 }
111 }
112}