1use std::mem;
2use futures::{AsyncSeek, AsyncSeekExt};
3use std::io::SeekFrom;
4use crate::error::MP4Error;
5
6#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
7pub enum BoxSize {
8 Known(usize),
9 Unknown
10}
11
12impl BoxSize {
13
14 pub fn from_size_without_self(size: usize) -> Self {
15 Self::Known(size + if cfg!(target_pointer_width = "64") {
16 mem::size_of::<u32>() + if size + mem::size_of::<u32>() > u32::MAX as usize {
17 mem::size_of::<u64>()
18 } else {
19 0
20 }
21 } else {
22 mem::size_of::<u32>()
23 })
24 }
25
26 pub fn byte_size(&self) -> usize {
27 match self {
28 BoxSize::Known(size) => {
29 if cfg!(target_pointer_width = "64") {
30 mem::size_of::<u32>() + if size > &(u32::MAX as usize) {
31 mem::size_of::<u64>()
32 } else {
33 0
34 }
35 } else {
36 mem::size_of::<u32>()
37 }
38 }
39 BoxSize::Unknown => mem::size_of::<u32>()
40 }
41 }
42
43 pub async fn ended<R: AsyncSeek + Unpin>(&self, start: u64, reader: &mut R) -> Result<bool, MP4Error> {
44 Ok(match self {
45 BoxSize::Known(size) => {
46 let size = *size as i64;
47 let mut pos = reader.seek(SeekFrom::Current(0)).await?;
48 let read = (pos - start) as i64;
49 if read > size {
50 reader.seek(SeekFrom::Current(size - read)).await?;
51 }
52 read >= size
53 }
54 BoxSize::Unknown => false
55 })
56 }
57}