1use std::convert::TryInto;
2
3use nom::branch::alt;
4use nom::bytes::complete::tag;
5use nom::number::complete::be_u32;
6
7use crate::amf0;
8use crate::amf3::read::AMF3Decoder;
9use crate::nom_utils::AMFResult;
10use crate::types::{AMFVersion, Header, Lso};
11use nom::combinator::all_consuming;
12
13const HEADER_VERSION: [u8; 2] = [0x00, 0xbf];
14const HEADER_SIGNATURE: [u8; 10] = [0x54, 0x43, 0x53, 0x4f, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00];
15const PADDING: [u8; 1] = [0x00];
16
17const FORMAT_VERSION_AMF0: u8 = 0x0;
18const FORMAT_VERSION_AMF3: u8 = 0x3;
19
20#[derive(Default)]
34pub struct Reader {
35 pub amf3_decoder: AMF3Decoder,
37}
38
39impl Reader {
40 fn parse_header<'a>(&self, i: &'a [u8]) -> AMFResult<'a, Header> {
41 let (i, _) = tag(HEADER_VERSION)(i)?;
42 let (i, l) = be_u32(i)?;
43 let (i, _) = tag(HEADER_SIGNATURE)(i)?;
44
45 let (i, name) = amf0::read::parse_string(i)?;
46
47 let (i, _) = tag(PADDING)(i)?;
48 let (i, _) = tag(PADDING)(i)?;
49 let (i, _) = tag(PADDING)(i)?;
50
51 let (i, version) = alt((tag(&[FORMAT_VERSION_AMF0]), tag(&[FORMAT_VERSION_AMF3])))(i)?;
52
53 let format_version: AMFVersion = version[0].try_into().unwrap();
55
56 Ok((
57 i,
58 Header {
59 length: l,
60 name: name.to_string(),
61 format_version,
62 },
63 ))
64 }
65
66 fn parse_inner<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Lso> {
67 let (i, header) = self.parse_header(i)?;
68 match header.format_version {
69 AMFVersion::AMF0 => {
70 let (i, body) = amf0::read::parse_body(i)?;
71 Ok((i, Lso { header, body }))
72 }
73
74 AMFVersion::AMF3 => {
75 let (i, body) = self.amf3_decoder.parse_body(i)?;
76 Ok((i, Lso { header, body }))
77 }
78 }
79 }
80
81 pub fn parse<'a>(&mut self, i: &'a [u8]) -> AMFResult<'a, Lso> {
83 all_consuming(|i| self.parse_inner(i))(i)
84 }
85}