flowly_flv/parser/tag/
meta.rs1use std::collections::HashMap;
2
3use bytes::Bytes;
4
5use crate::{
6 error::Error,
7 parser::{FlvParser, Parser},
8 reader::FlvReader,
9 tag::meta::{MetaDataDate, MetaDataValue, MetaTag},
10};
11
12const OBJECT_END_MARKER: [u8; 3] = [0x00, 0x00, 0x09];
13
14impl<E> Parser<E, MetaTag> for FlvParser {
15 type Error = Error<E>;
16
17 fn parse(&mut self, reader: &mut impl FlvReader) -> Result<MetaTag, Self::Error> {
19 let _tag = reader.read_u8()?;
20 let name = self.parse_meta_string(reader)?;
21
22 Ok(MetaTag {
24 name,
25 value: self.parse(reader)?,
26 })
27 }
28}
29
30impl FlvParser {
31 #[inline]
32 fn parse_meta_string<E>(&mut self, reader: &mut impl FlvReader) -> Result<Bytes, Error<E>> {
33 let len = reader.read_u16()? as usize;
34
35 Ok(reader.read_to_bytes(len as usize)?)
36 }
37
38 fn parse_meta_object<E>(
39 &mut self,
40 reader: &mut impl FlvReader,
41 ) -> Result<HashMap<Bytes, MetaDataValue>, Error<E>> {
42 let mut props = HashMap::new();
43
44 while reader.available() >= 3 && reader.peek(0..3)? != OBJECT_END_MARKER {
45 props.insert(self.parse_meta_string(reader)?, self.parse(reader)?);
46 }
47
48 Ok(props)
49 }
50}
51
52impl<E> Parser<E, MetaDataValue> for FlvParser {
53 type Error = Error<E>;
54
55 fn parse(&mut self, reader: &mut impl FlvReader) -> Result<MetaDataValue, Self::Error> {
57 Ok(match reader.read_u8()? {
58 0 => MetaDataValue::Number(reader.read_f64()?),
59 1 => MetaDataValue::Boolean(reader.read_u8()? != 0),
60 2 => MetaDataValue::String(self.parse_meta_string(reader)?),
61 3 => MetaDataValue::Object(self.parse_meta_object(reader)?),
62 5 => MetaDataValue::Null,
63 6 => MetaDataValue::Undefined,
64 7 => MetaDataValue::Reference(reader.read_u16()?),
65 8 => {
66 let _len = reader.read_u32()?;
67 MetaDataValue::ECMAArray(self.parse_meta_object(reader)?)
68 }
69 10 => {
70 let len = reader.read_u32()?;
71 let mut arr = Vec::with_capacity(len as usize);
72 for _ in 0..len {
73 arr.push(self.parse(reader)?);
74 }
75
76 MetaDataValue::StrictArray(arr)
77 }
78 11 => MetaDataValue::Date(MetaDataDate {
79 date_time: reader.read_f64()?,
80 local_date_time_offset: reader.read_i16()?,
81 }),
82 12 => {
83 let len = reader.read_u32()? as usize;
84
85 MetaDataValue::LongString(reader.read_to_bytes(len)?)
86 }
87 id => MetaDataValue::Unknown(id),
88 })
89 }
90}