mp4_atom/moov/trak/mdia/minf/dinf/dref/
mod.rs1mod url;
2mod urn;
3pub use url::*;
4pub use urn::*;
5
6use crate::*;
7
8#[derive(Debug, Clone, PartialEq, Eq, Default)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct Dref {
11 pub entries: Vec<DrefEntry>,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17#[non_exhaustive]
18pub enum DrefEntry {
19 Url(Url),
20 Urn(Urn),
21 Unknown(FourCC, Vec<u8>),
22}
23
24impl DrefEntry {
25 pub fn kind(&self) -> FourCC {
26 match self {
27 Self::Url(_) => Url::KIND,
28 Self::Urn(_) => Urn::KIND,
29 Self::Unknown(kind, _) => *kind,
30 }
31 }
32}
33
34impl Decode for DrefEntry {
35 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
36 let header = Header::decode(buf)?;
37 let size = header.size.unwrap_or(buf.remaining());
38 if size > buf.remaining() {
39 return Err(Error::OutOfBounds);
40 }
41
42 match header.kind {
43 kind if kind == Url::KIND => Url::decode_atom(&header, buf).map(Self::Url),
44 kind if kind == Urn::KIND => Urn::decode_atom(&header, buf).map(Self::Urn),
45 kind => {
46 let data = Vec::decode(&mut buf.slice(size))?;
47 buf.advance(size);
48 Ok(Self::Unknown(kind, data))
49 }
50 }
51 }
52}
53
54impl Encode for DrefEntry {
55 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
56 match self {
57 Self::Url(url) => url.encode(buf),
58 Self::Urn(urn) => urn.encode(buf),
59 Self::Unknown(kind, data) => {
60 Header {
61 kind: *kind,
62 size: Some(data.len()),
63 }
64 .encode(buf)?;
65 data.encode(buf)
66 }
67 }
68 }
69}
70
71impl From<Url> for DrefEntry {
72 fn from(url: Url) -> Self {
73 Self::Url(url)
74 }
75}
76
77impl From<Urn> for DrefEntry {
78 fn from(urn: Urn) -> Self {
79 Self::Urn(urn)
80 }
81}
82
83impl AtomExt for Dref {
84 type Ext = ();
85
86 const KIND_EXT: FourCC = FourCC::new(b"dref");
87
88 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
89 let entry_count = u32::decode(buf)?;
90 let mut entries = Vec::new();
91
92 for _ in 0..entry_count {
93 entries.push(DrefEntry::decode(buf)?);
94 }
95
96 Ok(Dref { entries })
97 }
98
99 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
100 let entry_count =
101 u32::try_from(self.entries.len()).map_err(|_| Error::TooLarge(Self::KIND))?;
102 entry_count.encode(buf)?;
103
104 for entry in &self.entries {
105 entry.encode(buf)?;
106 }
107
108 Ok(())
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 use std::io::Cursor;
116
117 const ENCODED_URN_AND_UNKNOWN: &[u8] = &[
118 0, 0, 0, 48, b'd', b'r', b'e', b'f', 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 21, b'u', b'r', b'n',
119 b' ', 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, b'l', b'o', b'c', 0, 0, 0, 0, 11, b'a', b'b',
120 b'c', b'd', 1, 2, 3,
121 ];
122
123 #[test]
124 fn decode_and_preserve_urn_and_unknown_entries() {
125 let dref = Dref::decode(&mut Cursor::new(ENCODED_URN_AND_UNKNOWN)).unwrap();
126
127 assert_eq!(
128 dref,
129 Dref {
130 entries: vec![
131 Urn {
132 name: "name".into(),
133 location: "loc".into(),
134 }
135 .into(),
136 DrefEntry::Unknown(FourCC::new(b"abcd"), vec![1, 2, 3]),
137 ],
138 }
139 );
140
141 let mut encoded = Vec::new();
142 dref.encode(&mut encoded).unwrap();
143 assert_eq!(encoded, ENCODED_URN_AND_UNKNOWN);
144 }
145}