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 #[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 #[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 pub fn from_bytes(input: &'a [u8], parser: &mut Parser) -> MltRefResult<'a, Layer<'a>> {
45 let (input, size) = parse_varint::<u32>(input)?;
46
47 let (input, tag) = parse_u8(input)?;
50 let size = size.checked_sub(1).ok_or(MltError::ZeroLayerSize)?;
52 let (input, value) = take(input, size)?;
53
54 let layer = match tag {
55 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 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}