xref: /xiu/protocol/rtmp/src/cache/metadata.rs (revision ea7993e4)
1 use {
2     super::errors::MetadataError,
3     crate::amf0::{amf0_reader::Amf0Reader, amf0_writer::Amf0Writer, Amf0ValueType},
4     bytes::BytesMut,
5     bytesio::{bytes_reader::BytesReader, bytes_writer::BytesWriter},
6 };
7 pub struct MetaData {
8     chunk_body: BytesMut,
9     // values: Vec<Amf0ValueType>,
10 }
11 
12 impl MetaData {
13     pub fn default() -> Self {
14         Self {
15             chunk_body: BytesMut::new(),
16             //values: Vec::new(),
17         }
18     }
19     //, values: Vec<Amf0ValueType>
20     pub fn save(&mut self, body: BytesMut) {
21         if self.is_metadata(body.clone()) {
22             self.chunk_body = body;
23         }
24     }
25 
26     //used for the http-flv protocol
27     pub fn remove_set_data_frame(&mut self) -> Result<BytesMut, MetadataError> {
28         let mut amf_writer: Amf0Writer = Amf0Writer::new(BytesWriter::new());
29         amf_writer.write_string(&String::from("@setDataFrame"))?;
30 
31         let (_, right) = self.chunk_body.split_at(amf_writer.len());
32 
33         Ok(BytesMut::from(right))
34     }
35 
36     pub fn is_metadata(&mut self, body: BytesMut) -> bool {
37         let reader = BytesReader::new(body);
38         let result = Amf0Reader::new(reader).read_all();
39 
40         let mut values: Vec<Amf0ValueType> = Vec::new();
41 
42         match result {
43             Ok(v) => {
44                 values.extend_from_slice(&v[..]);
45             }
46             Err(_) => return false,
47         }
48 
49         loop {
50             if values.len() < 2 {
51                 return false;
52             }
53 
54             match values.remove(0) {
55                 Amf0ValueType::UTF8String(str) => {
56                     if str != "@setDataFrame" {
57                         return false;
58                     }
59                 }
60                 _ => {
61                     return false;
62                 }
63             }
64 
65             match values.remove(0) {
66                 Amf0ValueType::UTF8String(str) => {
67                     if str != "onMetaData" {
68                         return false;
69                     }
70                 }
71                 _ => {
72                     return false;
73                 }
74             }
75             break;
76         }
77 
78         return true;
79     }
80 
81     pub fn get_chunk_body(&self) -> BytesMut {
82         return self.chunk_body.clone();
83     }
84 }
85