async_mp4/
size.rs

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}