pito_codecs/mp4/
source.rs1use std::io;
2use std::sync::Arc;
3
4pub trait ByteSource {
5 fn len(&self) -> u64;
6 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()>;
7 fn is_empty(&self) -> bool {
8 self.len() == 0
9 }
10}
11
12fn eof() -> io::Error {
13 io::Error::new(io::ErrorKind::UnexpectedEof, "read past end of byte source")
14}
15
16impl ByteSource for [u8] {
17 fn len(&self) -> u64 {
18 <[u8]>::len(self) as u64
19 }
20 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()> {
21 let start = usize::try_from(offset).map_err(|_| eof())?;
22 let end = start.checked_add(buf.len()).ok_or_else(eof)?;
23 let src = self.get(start..end).ok_or_else(eof)?;
24 buf.copy_from_slice(src);
25 Ok(())
26 }
27}
28
29impl ByteSource for Vec<u8> {
30 fn len(&self) -> u64 {
31 self.as_slice().len() as u64
32 }
33 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()> {
34 self.as_slice().read_at(offset, buf)
35 }
36}
37
38impl<T: ByteSource + ?Sized> ByteSource for &T {
39 fn len(&self) -> u64 {
40 (**self).len()
41 }
42 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()> {
43 (**self).read_at(offset, buf)
44 }
45}
46
47impl<T: ByteSource + ?Sized> ByteSource for Arc<T> {
48 fn len(&self) -> u64 {
49 (**self).len()
50 }
51 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()> {
52 (**self).read_at(offset, buf)
53 }
54}
55
56impl<T: ByteSource + ?Sized> ByteSource for Box<T> {
57 fn len(&self) -> u64 {
58 (**self).len()
59 }
60 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()> {
61 (**self).read_at(offset, buf)
62 }
63}
64
65#[cfg(not(target_arch = "wasm32"))]
66impl ByteSource for std::fs::File {
67 fn len(&self) -> u64 {
68 self.metadata().map(|m| m.len()).unwrap_or(0)
69 }
70 #[cfg(unix)]
71 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()> {
72 std::os::unix::fs::FileExt::read_exact_at(self, buf, offset)
73 }
74 #[cfg(windows)]
75 fn read_at(&self, mut offset: u64, mut buf: &mut [u8]) -> io::Result<()> {
76 use std::os::windows::fs::FileExt;
77 while !buf.is_empty() {
78 let n = self.seek_read(buf, offset)?;
79 if n == 0 {
80 return Err(eof());
81 }
82 offset += n as u64;
83 buf = &mut buf[n..];
84 }
85 Ok(())
86 }
87 #[cfg(not(any(unix, windows)))]
88 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<()> {
89 use std::io::{Read, Seek, SeekFrom};
90 let mut f = self;
91 f.seek(SeekFrom::Start(offset))?;
92 f.read_exact(buf)
93 }
94}