Skip to main content

mlt_core/frames/
layer.rs

1use std::borrow::Cow;
2use std::io;
3use std::io::Write;
4
5use integer_encoding::VarIntWriter as _;
6use utils::BinarySerializer as _;
7
8use crate::codecs::varint::parse_varint;
9use crate::frames::Unknown;
10use crate::frames::v01::Layer01;
11use crate::utils::{checked_sum2, parse_u8, take};
12use crate::{Decoder, EncodedLayer, Layer, MltError, MltRefResult, MltResult, Parser, utils};
13
14impl<'a> Layer<'a> {
15    /// Returns the inner `Layer01` if this is a Tag01 layer, or `None` otherwise.
16    #[must_use]
17    pub fn as_layer01(&self) -> Option<&Layer01<'a>> {
18        match self {
19            Layer::Tag01(l) => Some(l),
20            Layer::Unknown(_) => None,
21        }
22    }
23
24    /// Returns the inner `Layer01` if this is a Tag01 layer, or `None` otherwise.
25    #[must_use]
26    pub fn as_layer01_mut(&mut self) -> Option<&mut Layer01<'a>> {
27        match self {
28            Layer::Tag01(l) => Some(l),
29            Layer::Unknown(_) => None,
30        }
31    }
32
33    pub fn decoded_layer01_mut(&mut self, dec: &mut Decoder) -> Result<&mut Layer01<'a>, MltError> {
34        let layer = self
35            .as_layer01_mut()
36            .ok_or(MltError::NotDecoded("expected Tag01 layer"))?;
37        layer.decode_id(dec)?;
38        layer.decode_geometry(dec)?;
39        Ok(layer)
40    }
41
42    /// Parse a single tuple that consists of `size (varint)`, `tag (varint)`, and `value (bytes)`.
43    /// Reserves memory for decoded data against the parser's budget.
44    pub fn from_bytes(input: &'a [u8], parser: &mut Parser) -> MltRefResult<'a, Layer<'a>> {
45        let (input, size) = parse_varint::<u32>(input)?;
46
47        // tag is a varint, but we know fewer than 127 tags for now,
48        // so we can use a faster u8 and fail if it is bigger than 127.
49        let (input, tag) = parse_u8(input)?;
50        // 1 byte must be parsed for the tag, so if size is 0, it's invalid
51        let size = size.checked_sub(1).ok_or(MltError::ZeroLayerSize)?;
52        let (input, value) = take(input, size)?;
53
54        let layer = match tag {
55            // For now, we only support tag 0x01 layers, but more will be added soon
56            1 => Layer::Tag01(Layer01::from_bytes(value, parser)?),
57            tag => Layer::Unknown(Unknown { tag, value }),
58        };
59
60        Ok((input, layer))
61    }
62
63    pub fn decode_all(&mut self, dec: &mut Decoder) -> MltResult<()> {
64        match self {
65            Layer::Tag01(layer) => layer.decode_all(dec),
66            Layer::Unknown(_) => Ok(()),
67        }
68    }
69}
70
71impl EncodedLayer {
72    /// Write layer's binary representation to a Write stream
73    pub fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
74        let (tag, buffer) = match self {
75            EncodedLayer::Tag01(layer) => {
76                let mut buffer = Vec::new();
77                layer.write_to(&mut buffer)?;
78                (1_u8, Cow::Owned(buffer))
79            }
80            EncodedLayer::Unknown(unknown) => (unknown.tag, Cow::Borrowed(&unknown.value)),
81        };
82
83        let buffer_len = u32::try_from(buffer.len()).map_err(MltError::from)?;
84        let size = checked_sum2(buffer_len, 1)?;
85        writer.write_varint(size)?;
86        writer.write_u8(tag)?;
87        writer.write_all(&buffer)
88    }
89}